Gutenberg block outputting JSON in front end – is this normal?

Yes this is normal for post content, but it should never make it to the frontend if you’ve processed your content correctly, e.g. by using the_content() to display it. This implies you’re displaying raw content that has not gone through the_content filter