uber-go/zap · error

invalid increase level, as level %q is allowed by increased

Error message

invalid increase level, as level %q is allowed by increased level, but not by existing core

What it means

NewIncreaseLevelCore wraps a Core with a level filter that may only RAISE the effective logging level. It scans all levels from max to min; if the new LevelEnabler enables a level that the existing core does not (i.e. a decrease), construction fails with this error.

Source

Thrown at zapcore/increase_level.go:42

type levelFilterCore struct {
	core  Core
	level LevelEnabler
}

var (
	_ Core           = (*levelFilterCore)(nil)
	_ leveledEnabler = (*levelFilterCore)(nil)
)

// NewIncreaseLevelCore creates a core that can be used to increase the level of
// an existing Core. It cannot be used to decrease the logging level, as it acts
// as a filter before calling the underlying core. If level decreases the log level,
// an error is returned.
func NewIncreaseLevelCore(core Core, level LevelEnabler) (Core, error) {
	for l := _maxLevel; l >= _minLevel; l-- {
		if !core.Enabled(l) && level.Enabled(l) {
			return nil, fmt.Errorf("invalid increase level, as level %q is allowed by increased level, but not by existing core", l)
		}
	}

	return &levelFilterCore{core, level}, nil
}

func (c *levelFilterCore) Enabled(lvl Level) bool {
	return c.level.Enabled(lvl)
}

func (c *levelFilterCore) Level() Level {
	return LevelOf(c.level)
}

func (c *levelFilterCore) With(fields []Field) Core {
	return &levelFilterCore{c.core.With(fields), c.level}
}

View on GitHub (pinned to bbd4ecbd87)

Solutions

  1. Ensure the passed LevelEnabler's level is >= the base core's level (e.g. increase from Info to Error, not the reverse).
  2. If you need to lower verbosity, rebuild the base core/logger with the desired level instead of using NewIncreaseLevelCore.
  3. Check that the atomic level backing the enabler wasn't mutated to a lower value before the call.

Example fix

// before
zapcore.NewIncreaseLevelCore(core, zap.NewAtomicLevelAt(zapcore.DebugLevel)) // decrease
// after
zapcore.NewIncreaseLevelCore(core, zap.NewAtomicLevelAt(zapcore.ErrorLevel)) // increase
Defensive patterns

Strategy: validation

Validate before calling

newLvl := zap.NewAtomicLevelAt(zapcore.ErrorLevel)
for l := zapcore.FatalLevel; l >= zapcore.DebugLevel; l-- {
    if newLvl.Enabled(l) && !baseCore.Enabled(l) {
        return fmt.Errorf("cannot decrease to %s", l)
    }
}
core, err := zapcore.NewIncreaseLevelCore(baseCore, newLvl)

Prevention

When it happens

Trigger: Calling zapcore.NewIncreaseLevelCore(core, level) where level.Enabled(l) is true for some l that core.Enabled(l) is false — e.g. wrapping a core configured at ErrorLevel with an enabler for InfoLevel, or using an atomic level that was lowered.

Common situations: Dynamically changing log levels at runtime via zap.AtomicLevel and wrapping with NewIncreaseLevelCore while passing a lower verbosity than the base config; tests asserting level decreases are rejected; misordering WrapCore options.

Related errors


AI-assisted analysis of uber-go/zap@bbd4ecbd87 (2026-08-31). Data as JSON: /api/errors/26fc601691bea084. Report an issue: GitHub.