gofiber/fiber · error

ErrTagInvalid

ErrTagInvalid

Error message

logger: tag name and function are required

What it means

logger.RegisterTag returns ErrTagInvalid ("logger: tag name and function are required") and MustRegisterTag panics with that error when tag is empty or fn is nil. The tag registry needs both a non-empty name and a non-nil renderer; otherwise the tag could never produce output and would shadow/overwrite valid registrations ambiguously.

Source

Thrown at middleware/logger/tags.go:85

// Registered tags are available to logger middleware instances created after
// registration and can be overridden per instance with Config.CustomTags.
// Re-registering a tag replaces the existing tag function.
func RegisterTag(tag string, fn LogFunc) error {
	if tag == "" || fn == nil {
		return ErrTagInvalid
	}

	registeredTags.Lock()
	defer registeredTags.Unlock()

	registeredTags.m[tag] = fn
	return nil
}

// MustRegisterTag registers a global logger middleware tag and panics on failure.
func MustRegisterTag(tag string, fn LogFunc) {
	if err := RegisterTag(tag, fn); err != nil {
		panic(err)
	}
}

// createTagMap function merged the default with the custom tags
func createTagMap(cfg *Config) map[string]LogFunc {
	// Set default tags
	tagFunctions := map[string]LogFunc{
		TagReferer: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) {
			return writeSanitizedString(output, c.Get(fiber.HeaderReferer))
		},
		TagProtocol: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) {
			return output.WriteString(c.Protocol())
		},
		TagScheme: func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) {
			// Scheme echoes X-Forwarded-Proto / X-Url-Scheme once the proxy is
			// trusted, so it is request-derived like ${ips} and ${ua}.
			return writeSanitizedString(output, c.Scheme())
		},

View on GitHub (pinned to a105acad6c)

Solutions

  1. Pass a non-empty tag name and a non-nil LogFunc to MustRegisterTag.
  2. Skip empty/nil entries: if name != "" && fn != nil { logger.MustRegisterTag(name, fn) }.
  3. When using RegisterTag (non-Must), check the returned error and log/handle it instead of ignoring.

Example fix

// before
logger.MustRegisterTag("", func(output logger.Buffer, c fiber.Ctx, _ *logger.Data, _ string) (int, error) {
    return output.WriteString("x")
})

// after
logger.MustRegisterTag("tenant", func(output logger.Buffer, c fiber.Ctx, _ *logger.Data, _ string) (int, error) {
    return output.WriteString(c.Locals("tenant").(string))
})
Defensive patterns

Strategy: validation

Validate before calling

func safeRegisterTag(name string, fn logger.LogFunc) error {
    if name == "" || fn == nil {
        return logger.ErrTagInvalid
    }
    return logger.RegisterTag(name, fn)
}

Type guard

func isValidTagRegistration(name string, fn logger.LogFunc) bool {
    return name != "" && fn != nil
}

Prevention

When it happens

Trigger: logger.MustRegisterTag("", fn), logger.MustRegisterTag("foo", nil), or RegisterTag used directly with the error ignored and later New() failing because the tag was never actually stored.

Common situations: Registering tags in a loop over user config where a name is empty; a LogFunc built by a helper that returns nil on an error branch; refactor that accidentally passes the function in the wrong argument position.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/60e6c121dbebe14f. Report an issue: GitHub.