Quick answer: The most common cause is that the bbcode_enabled property is set to false on the RichTextLabel node. In Godot 4, this property defaults to false, so you must explicitly enable it in the Inspector or via code using rich_text_label.bbcode_enabled = true.

Here is how to fix Godot richtextlabel bbcode not rendering. You added a RichTextLabel to your Godot 4 scene, typed in some BBCode tags like [b] and [color], and instead of formatted text you see the raw tags printed on screen. The square brackets just sit there as literal characters. This is one of the most common RichTextLabel issues in Godot 4, and the fix is straightforward once you know where to look.

The Symptom

When you run your scene, the RichTextLabel displays the full BBCode markup as visible text. Instead of seeing bold text, you see the string [b]bold text[/b] rendered literally. Color tags, italic tags, font size tags — none of them are interpreted. The node behaves as if it were a plain Label, ignoring all formatting instructions.

This happens both when you set the text in the Inspector and when you assign it from GDScript at runtime. You might also notice that append_text() calls produce the same raw output, leading you to believe the node is fundamentally broken. It is not — it just needs one critical property toggled on.

What Causes This

In Godot 4, the RichTextLabel node has a property called bbcode_enabled that defaults to false. When this property is off, the node treats its text property as plain text and does not attempt to parse any BBCode tags. Every square bracket is rendered as a literal character.

This catches developers off guard because the node is called RichTextLabel, which implies it should handle rich formatting out of the box. The reasoning behind the default is that RichTextLabel can also be used as a high-performance plain text display with features like word wrapping and selection that regular Label nodes handle differently. Godot keeps BBCode parsing off by default to avoid unexpected behavior when developers use RichTextLabel purely for its layout capabilities.

A second common cause is using the wrong method to set text. The add_text() method always inserts plain text regardless of the bbcode_enabled setting. If you are calling add_text() thinking it will parse your BBCode, it will not. You need append_text() or the text property instead.

A third cause is malformed BBCode syntax. Godot 4 changed several tag names from Godot 3. For example, the old [font size=20] syntax is now [font_size=20]. If you are porting a project from Godot 3, your tags may silently fail to parse.

The Fix

Step 1: Enable BBCode parsing. Select your RichTextLabel node in the scene tree, then in the Inspector panel, find the BBCode section and check the BBCode Enabled checkbox. Alternatively, enable it from code:

# Enable BBCode parsing on your RichTextLabel
@onready var label = $RichTextLabel

func _ready():
  label.bbcode_enabled = true
  label.text = "[b]Bold[/b] and [color=red]red[/color] text"

Step 2: Use the correct method for dynamic text. If you are building text dynamically at runtime, use append_text() to add BBCode content. Do not use add_text() as it bypasses BBCode parsing entirely:

# Correct: append_text() parses BBCode
label.clear()
label.append_text("[b]Health:[/b] ")
label.append_text("[color=green]100[/color]")

# Wrong: add_text() always inserts plain text
# label.add_text("[b]Health:[/b] ")  # Shows raw tags

Step 3: Verify your tag syntax for Godot 4. If you migrated from Godot 3, update any deprecated tag formats. Here are the most common changes:

# Godot 3 (old) → Godot 4 (new)
# [font size=20]  →  [font_size=20]
# [font color=red] →  [color=red]
# [table cols=2]  →  [table=2]

# Example of correct Godot 4 BBCode
var bbcode = "[font_size=24][b]Title[/b][/font_size]\n"
bbcode += "[color=#aaaaaa]Subtitle text[/color]\n"
bbcode += "[ul]Item one\nItem two\nItem three[/ul]"
label.text = bbcode

Step 4: Handle edge cases with parse_bbcode(). If you need to completely replace the label content and ensure a fresh parse, use parse_bbcode() which clears the existing content and parses the new string in one call:

# parse_bbcode() clears and re-parses in one step
func update_dialog(speaker: String, message: String):
  var formatted = "[b]%s:[/b] %s" % [speaker, message]
  label.parse_bbcode(formatted)

Why This Works

The bbcode_enabled property acts as a master switch for the entire BBCode parsing pipeline inside RichTextLabel. When it is false, the node skips the parsing step entirely and feeds the raw string directly to the text rendering system. Setting it to true activates the parser that tokenizes BBCode tags, builds a formatting stack, and applies styles to each text segment before rendering.

The distinction between append_text() and add_text() exists because RichTextLabel supports both plain and formatted content simultaneously. You can mix plain text segments with BBCode segments in the same label. The add_text() method intentionally skips parsing so you can insert user-generated content without worrying about accidental BBCode injection — useful for chat systems or displaying player names that might contain square brackets.

The Godot 4 tag syntax changes are part of a broader cleanup of the BBCode implementation. The new format uses underscores to separate words in tag names, aligning with GDScript naming conventions and making the parser more consistent internally.

Related Issues

If your RichTextLabel is working but the text overflows or does not scroll, check out our guide on fixing ScrollContainer not scrolling — RichTextLabel inside a ScrollContainer requires specific size flag configuration to scroll properly.

For issues with UI elements not receiving input correctly when layered with RichTextLabel, see our post on fixing UI clicks passing through to the game world. RichTextLabel URL tags in particular require correct mouse filter settings to handle click events.

If you are trying to display images inside your RichTextLabel using the [img] tag and they appear stretched or incorrectly sized, our TextureRect image stretching fix covers related aspect ratio concepts that also apply to inline images in BBCode.

Enable BBCode. Use append_text. Check your tag syntax.