hashicorp/terraform · error

global logger is not an InterceptLogger

Error message

global logger is not an InterceptLogger

What it means

Panics in RegisterSink (logging.go:69). It type-asserts the package-global logger to hclog.InterceptLogger to attach a file sink; if the global logger has been replaced with a plain hclog.Logger the assertion fails and panics.

Source

Thrown at internal/logging/logging.go:69

	GraphTrace = os.Getenv(envGraphTrace) != ""
)

func init() {
	logger = newHCLogger("")
	logWriter = logger.StandardWriter(&hclog.StandardLoggerOptions{InferLevels: true})

	// set up the default std library logger to use our output
	log.SetFlags(0)
	log.SetPrefix("")
	log.SetOutput(logWriter)
}

// SetupTempLog adds a new log sink which writes all logs to the given file.
func RegisterSink(f *os.File) {
	l, ok := logger.(hclog.InterceptLogger)
	if !ok {
		panic("global logger is not an InterceptLogger")
	}

	if f == nil {
		return
	}

	l.RegisterSink(hclog.NewSinkAdapter(&hclog.LoggerOptions{
		Level:  hclog.Trace,
		Output: f,
	}))
}

// LogOutput return the default global log io.Writer
func LogOutput() io.Writer {
	return logWriter
}

// HCLogger returns the default global hclog logger

View on GitHub (pinned to c9def3e214)

Solutions

  1. Do not replace the global logger with a non-Intercept logger.
  2. If you must replace it, wrap with hclog.NewInterceptLogger so the assertion holds.
  3. Leave logger initialization to logging.newHCLogger which already produces an InterceptLogger.

Example fix

// before
logger = hclog.New(&hclog.LoggerOptions{Name: "x"})
// after
logger = hclog.NewInterceptLogger(&hclog.LoggerOptions{Name: "x"})
Defensive patterns

Strategy: type-guard

Validate before calling

func canRegisterSink(l hclog.Logger) error {
    if _, ok := l.(hclog.InterceptLogger); !ok {
        return fmt.Errorf("global logger must be InterceptLogger")
    }
    return nil
}

Type guard

func isInterceptLogger(l hclog.Logger) bool {
    _, ok := l.(hclog.InterceptLogger)
    return ok
}

Prevention

When it happens

Trigger: Code overwrites the package-global logger (e.g. via reassigning logging's logger or embedding Terraform as a library) with a non-Intercept hclog.Logger, then RegisterSink runs (when TF_LOG_PATH / temp logging is configured).

Common situations: Test harnesses or forks that swap in a custom logger; embedding Terraform as a library and replacing the logger with hclog.New instead of hclog.NewInterceptLogger.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/46a15adf81f3bc6a. Report an issue: GitHub.