SigNoz/signoz · error · model.ApiError

failed to get email from context

Error message

failed to get email from context

What it means

insertPipeline in the log-parsing-pipeline DB layer extracts auth claims from the request context via authtypes.ClaimsFromContext; when that fails it maps the problem to an UnauthorizedError with this message. Despite the wording ('get email'), the real cause is missing/invalid authentication claims in ctx — the context was not authenticated (or the claims middleware did not run) before ApplyPipelines -> insertPipeline.

Source

Thrown at pkg/query-service/app/logparsingpipeline/db.go:53

func (r *Repo) insertPipeline(
	ctx context.Context, orgID valuer.UUID, postable *pipelinetypes.PostablePipeline,
) (*pipelinetypes.GettablePipeline, error) {
	if err := postable.IsValid(); err != nil {
		return nil, errors.WithAdditionalf(err, "pipeline is not valid")
	}

	rawConfig, err := json.Marshal(postable.Config)
	if err != nil {
		return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to unmarshal postable pipeline config")
	}
	filter, err := json.Marshal(postable.Filter)
	if err != nil {
		return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to marshal postable pipeline filter")
	}

	claims, errv2 := authtypes.ClaimsFromContext(ctx)
	if errv2 != nil {
		return nil, model.UnauthorizedError(fmt.Errorf("failed to get email from context"))
	}

	insertRow := &pipelinetypes.GettablePipeline{
		StoreablePipeline: pipelinetypes.StoreablePipeline{
			OrgID: orgID.String(),
			Identifiable: types.Identifiable{
				ID: valuer.GenerateUUID(),
			},
			OrderID:      postable.OrderID,
			Enabled:      postable.Enabled,
			Name:         postable.Name,
			Alias:        postable.Alias,
			Description:  postable.Description,
			FilterString: string(filter),
			ConfigJSON:   string(rawConfig),
			TimeAuditable: types.TimeAuditable{
				CreatedAt: time.Now(),
			},

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Ensure the call is made with an authenticated context — attach a valid JWT/API key so the auth middleware injects claims before ApplyPipelines runs.
  2. In tests, inject claims explicitly (e.g. authtypes.InjectContext(ctx, claims) or your project's helper) instead of context.Background().
  3. Verify middleware/route ordering so the pipeline endpoints are behind the auth layer.
  4. If forwarding between services, propagate the Authorization metadata so ClaimsFromContext succeeds.

Example fix

// before
pipeline, err := qs.ApplyPipelines(context.Background(), req) // no claims -> unauthorized

// after
ctx := authtypes.InjectClaimsIntoContext(ctx, authtypes.Claims{Email: "user@example.com", UserID: ...})
pipeline, err := qs.ApplyPipelines(ctx, req)
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := authtypes.ClaimsFromContext(ctx); err != nil {
	return model.UnauthorizedError(fmt.Errorf("request is not authenticated"))
}

Type guard

func hasClaims(ctx context.Context) bool {
	_, err := authtypes.ClaimsFromContext(ctx)
	return err == nil
}

Try / catch

pipeline, err := qs.ApplyPipelines(ctx, req)
if err != nil {
	if errors.Is(err, errors.ErrUnauthenticated) || strings.Contains(err.Error(), "failed to get email from context") {
		// re-authenticate / refresh token and retry once, or return 401
	}
	return err
}

Prevention

When it happens

Trigger: Calling ApplyPipelines (which calls insertPipeline) with a context that carries no auth claims: unauthenticated gRPC/HTTP context, claims not propagated through a background job or test harness, or an expired/invalid JWT that the claims middleware refused to attach.

Common situations: Integration tests calling ApplyPipelines with context.Background(); internal services invoking the pipeline API without forwarding authorization headers/claims; middleware ordering that skips auth on a new route; expired API token.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/1866b43b1af5dff7. Report an issue: GitHub.