gofiber/fiber · warning
log: context tag is reserved
Error message
log: context tag is reserved
What it means
Returned by log.SetContextTemplate and log.RegisterContextTag when a caller tries to register or override the reserved context tag TagContextValue (the "value:" tag). Fiber reserves that tag because it renders the default contextual value field; the framework reinstalls it after applying CustomTags so user overrides would be silently dropped. Returning the error makes the collision explicit at config time.
Solutions
- Remove the "value:" entry from the CustomTags map passed to SetContextTemplate.
- If you need custom value rendering, register it under a different tag name (e.g. "myvalue:") and reference that tag in the format string.
- If the tag map is generated dynamically, filter out TagContextValue before passing it in.
Example fix
// before
SetContextTemplate(ContextConfig{
Format: "${value} ${custom}",
CustomTags: map[string]ContextTagFunc{
"value:": myValueFn, // collides with reserved tag
"custom": myCustomFn,
},
})
// after
SetContextTemplate(ContextConfig{
Format: "${value} ${custom}",
CustomTags: map[string]ContextTagFunc{
"custom": myCustomFn,
},
}) Defensive patterns
Strategy: validation
Validate before calling
func sanitizeContextTags(in map[string]ContextTagFunc) map[string]ContextTagFunc {
out := make(map[string]ContextTagFunc, len(in))
for k, v := range in {
if k == log.TagContextValue {
continue // reserved; SetContextTemplate would reject it
}
out[k] = v
}
return out
} Try / catch
if err := log.SetContextTemplate(cfg); err != nil {
if errors.Is(err, log.ErrContextTagReserved) {
// strip the reserved key from CustomTags and retry, or surface config error
}
return err
} Prevention
- Never add "value:" to a CustomTags map by hand; treat TagContextValue as read-only.
- When generating CustomTags from config, filter out reserved names before calling SetContextTemplate.
- Prefer per-instance CustomTags over global RegisterContextTag to avoid collisions.
When it happens
Trigger: Calling SetContextTemplate(ContextConfig{CustomTags: map[string]ContextTagFunc{"value:": fn}}), or calling RegisterContextTag("value:", fn). Both paths short-circuit before mutating global state.
Common situations: An application that builds CustomTags programmatically (e.g. from a config file or list of tag names) and accidentally includes the literal "value:" key. Copy-pasting a tag map that already contained the value tag.
Related errors
- ErrUnknownTag
- log: context tag name and function are required
- logger: tag name and function are required
- logger: unknown template tag
- add: invalid http method
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/9433e456b1d96ecf.
Report an issue: GitHub.
Appendix: 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 a105acad6c)