gofiber/fiber · error · ErrContextTagReserved
log: context tag is reserved
Error message
log: context tag is reserved
What it means
ErrContextTagReserved ('log: context tag is reserved', log/context.go:87) is returned by log.RegisterContextTag (log/context.go:140) and SetContextTemplate (log/context.go:96) when the caller tries to register or override the reserved tag 'value:' (TagContextValue). That tag is the built-in renderer for ${value:KEY} context-value lookups and is re-installed by Fiber itself, so user overrides are rejected to preserve its semantics.
Source
Thrown at log/context.go:87
// contextTemplate holds the precompiled format. Loads on the log hot path
// happen lock-free; rebuilds (write side) hold contextMu.
var contextTemplate atomic.Pointer[logtemplate.Template[any, ContextData]]
var (
// contextMu guards rebuilds of contextFormat / contextTags. Readers of
// the compiled template (writeContext) use contextTemplate.Load directly.
contextMu sync.RWMutex
contextFormat = DefaultFormat
contextTags = defaultContextTagMap()
)
var (
// ErrContextTagInvalid is returned by RegisterContextTag and SetContextTemplate
// when the supplied tag name or renderer is empty.
ErrContextTagInvalid = errors.New("log: context tag name and function are required")
// ErrContextTagReserved is returned by RegisterContextTag and SetContextTemplate
// when the caller attempts to override the reserved TagContextValue ("value:") tag.
ErrContextTagReserved = errors.New("log: context tag is reserved")
)
// SetContextTemplate configures contextual fields rendered by WithContext for Fiber's default logger.
// Pass an empty ContextConfig (or ContextConfig{Format: DefaultFormat}) to disable contextual fields.
// It returns an error if config.Format cannot be parsed or if config.CustomTags attempts to
// override the reserved TagContextValue tag.
func SetContextTemplate(config ContextConfig) error {
if _, ok := config.CustomTags[TagContextValue]; ok {
return ErrContextTagReserved
}
contextMu.Lock()
defer contextMu.Unlock()
// Cloning the live tag map preserves prior RegisterContextTag entries —
// callers that interleave RegisterContextTag with SetContextTemplate
// expect the registration to remain visible. CustomTags layer on top.
tags := maps.Clone(contextTags)View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Choose a different, non-reserved tag name for your custom renderer (e.g. 'myvalue' or 'data:').
- Filter 'value:' out of any auto-generated CustomTags map before calling SetContextTemplate.
- To add context values, rely on the built-in ${value:KEY} tag instead of overriding it.
Example fix
// before
log.SetContextTemplate(log.ContextConfig{
CustomTags: map[string]log.ContextTagFunc{
"value:": myRenderer, // reserved -> ErrContextTagReserved
},
Format: "${value:userId}",
})
// after
log.SetContextTemplate(log.ContextConfig{
CustomTags: map[string]log.ContextTagFunc{
"myvalue:": myRenderer, // custom parametric tag
},
Format: "${myvalue:userId}",
}) Defensive patterns
Strategy: validation
Validate before calling
// Strip the reserved tag from auto-generated CustomTags.
delete(customTags, log.TagContextValue) // "value:"
if err := log.SetContextTemplate(log.ContextConfig{CustomTags: customTags, Format: fmtStr}); err != nil {
return err
} Try / catch
if err := log.RegisterContextTag(tag, fn); err != nil {
if errors.Is(err, log.ErrContextTagReserved) {
log.Printf("tag %q is reserved; rename it", tag)
return
}
return err
} Prevention
- Never attempt to register the reserved 'value:' tag.
- Filter reserved names out of generated CustomTags maps.
- Reuse the built-in ${value:KEY} tag for context-value lookups instead of overriding it.
When it happens
Trigger: Calling RegisterContextTag("value:", fn), or passing CustomTags: map[string]ContextTagFunc{"value:": fn} to SetContextTemplate. Any attempt to claim the reserved name yields this error. Must variants panic with it.
Common situations: Wanting a generic 'value' tag and not realizing 'value:' is reserved, or programmatically registering tags from a list that happens to include 'value:'. Confusing the bare vs parametric forms.
Related errors
- log: context tag name and function are required
- logtemplate: unknown tag
- min constraint requires an argument
- max constraint requires an argument
- range constraint requires two arguments
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/9433e456b1d96ecf.json.
Report an issue: GitHub.