googleapis/mcp-toolbox · error

unable to get logger from ctx: %s

Error message

unable to get logger from ctx: %s

What it means

This error is returned when util.LoggerFromContext(ctx) cannot find a logger in the context passed to the HTTP source's Initialize. The toolbox pipeline normally injects a slog logger into the context; receiving this error means Initialize was invoked with a bare context that skipped that instrumentation step.

Source

Thrown at internal/sources/http/http.go:103

}

// Initialize initializes an HTTP Source instance.
func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	duration, err := time.ParseDuration(r.Timeout)
	if err != nil {
		return nil, fmt.Errorf("unable to parse Timeout string as time.Duration: %s", err)
	}

	var tr *http.Transport
	if defaultTr, ok := http.DefaultTransport.(*http.Transport); ok {
		tr = defaultTr.Clone()
	} else {
		tr = &http.Transport{}
	}

	logger, err := util.LoggerFromContext(ctx)
	if err != nil {
		return nil, fmt.Errorf("unable to get logger from ctx: %s", err)
	}

	if r.DisableSslVerification {
		tr.TLSClientConfig = &tls.Config{
			InsecureSkipVerify: true,
		}

		logger.WarnContext(ctx, "WARNING: TLS certificate verification is skipped (InsecureSkipVerify: true) for HTTP source %s. This exposes all traffic for this source to Man-in-the-Middle (MITM) attacks. Do not use in production.", r.Name)
	}

	// Validate BaseURL
	parsedURL, err := url.ParseRequestURI(r.BaseURL)
	if err != nil {
		return nil, fmt.Errorf("failed to parse BaseUrl %v", err)
	}

	allowedRanges, err := parseCIDRs(r.AllowedIPRanges)
	if err != nil {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Initialize sources through the standard toolbox server startup path, which injects the logger into the context
  2. If calling Initialize directly, attach a logger first using the same util helper the server uses (e.g. util.WithLogger(ctx, logger) or equivalent)
  3. In tests, build the context with the util logger helper before invoking Initialize

Example fix

// before
src, err := cfg.Initialize(context.Background(), tracer)
// after
ctx := util.NewContextWithLogger(context.Background(), slog.Default())
src, err := cfg.Initialize(ctx, tracer)
Defensive patterns

Strategy: fallback

Validate before calling

// ensure a logger-bearing context before Initialize
if ctx.Value(loggerKey) == nil {
    ctx = util.NewContextWithLogger(ctx, slog.Default())
}

Try / catch

src, err := cfg.Initialize(ctx, tracer)
if err != nil && strings.Contains(err.Error(), "unable to get logger from ctx") {
    log.Fatalf("initialize sources only via the toolbox server path or inject a logger first: %v", err)
}

Prevention

When it happens

Trigger: Config.Initialize(ctx, tracer) is called with a ctx that never had a logger attached via the util logging middleware/context helper — e.g. direct programmatic construction of the source outside the normal server startup path, or a custom caller building sources without the toolbox's context decoration.

Common situations: Embedding the toolbox as a library and calling source Initialize directly with context.Background(); tests constructing sources without the logger-injecting middleware; refactors that dropped the logger setup before initialization.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/09875c00b0b88388. Report an issue: GitHub.