go-kit/kit · error · ErrPolicyContextMissing
CasbinPolicy is required in context
Error message
CasbinPolicy is required in context
What it means
Sentinel error from go-kit's Casbin authorization middleware. It means the access-control policy was not present in the request context under CasbinPolicyContextKey when casbin.NewEnforcer(...) ran. The policy is either a path to a policy .csv file or an implementation of the casbin/persist Adapter interface; without it the Enforcer has no rules to evaluate and construction fails (older revisions map the nil check to this exact sentinel).
Source
Thrown at auth/casbin/middleware.go:36
// CasbinPolicyContextKey holds the key to store the access control policy
// in context, it can be a path to policy file or an implementation of
// casbin/persist Adapter interface.
CasbinPolicyContextKey contextKey = "CasbinPolicy"
// CasbinEnforcerContextKey holds the key to retrieve the active casbin
// Enforcer.
CasbinEnforcerContextKey contextKey = "CasbinEnforcer"
)
var (
// ErrModelContextMissing denotes a casbin model was not passed into
// the parsing of middleware's context.
ErrModelContextMissing = errors.New("CasbinModel is required in context")
// ErrPolicyContextMissing denotes a casbin policy was not passed into
// the parsing of middleware's context.
ErrPolicyContextMissing = errors.New("CasbinPolicy is required in context")
// ErrUnauthorized denotes the subject is not authorized to do the action
// intended on the given object, based on the context model and policy.
ErrUnauthorized = errors.New("Unauthorized Access")
)
// NewEnforcer checks whether the subject is authorized to do the specified
// action on the given object. If a valid access control model and policy
// is given, then the generated casbin Enforcer is stored in the context
// with CasbinEnforcer as the key.
func NewEnforcer(
subject string, object interface{}, action string,
) endpoint.Middleware {
return func(next endpoint.Endpoint) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
casbinModel := ctx.Value(CasbinModelContextKey)
casbinPolicy := ctx.Value(CasbinPolicyContextKey)
enforcer, err := stdcasbin.NewEnforcer(casbinModel, casbinPolicy)View on GitHub (pinned to 78fbbceece)
Solutions
- Set the policy alongside the model: context.WithValue(ctx, casbin.CasbinPolicyContextKey, "rbac_policy.csv") or your persist.Adapter instance
- Verify both keys are set in the same middleware/RequestFunc and that it wraps the casbin middleware
- Confirm the policy file path is correct and readable at runtime (absolute path or correct working dir)
- If policy lives in a database, register your casbin adapter under the same context key
Example fix
// before: only the model is injected ctx = context.WithValue(ctx, casbin.CasbinModelContextKey, "rbac_model.conf") // -> "CasbinPolicy is required in context" // after: inject BOTH model and policy ctx = context.WithValue(ctx, casbin.CasbinModelContextKey, "rbac_model.conf") ctx = context.WithValue(ctx, casbin.CasbinPolicyContextKey, "rbac_policy.csv") // or with a DB-backed policy: // ctx = context.WithValue(ctx, casbin.CasbinPolicyContextKey, mySQLAdapter)
Defensive patterns
Strategy: validation
Validate before calling
func casbinInputsPresent(ctx context.Context) error {
if ctx.Value(casbin.CasbinModelContextKey) == nil {
return casbin.ErrModelContextMissing
}
if ctx.Value(casbin.CasbinPolicyContextKey) == nil {
return casbin.ErrPolicyContextMissing
}
return nil
} Type guard
func hasCasbinPolicy(ctx context.Context) bool {
return ctx.Value(casbin.CasbinPolicyContextKey) != nil
} Try / catch
resp, err := ep(ctx, req)
if err != nil {
switch {
case errors.Is(err, casbin.ErrPolicyContextMissing):
// configuration bug: 500 + alert
case errors.Is(err, casbin.ErrUnauthorized):
// 403
default:
// 500
}
} Prevention
- Set model and policy in the same middleware function — one without the other is always a bug
- If the policy is a file path, stat it at startup so a missing file fails fast at boot, not per request
- Cover the full middleware chain in an integration test that asserts context keys are populated
When it happens
Trigger: Storing only the model in context but not the policy (context.WithValue with CasbinPolicyContextKey missing); passing a policy path that is empty; using a custom persist.Adapter but forgetting to put it in context; enforcer middleware ordered before the injection middleware so ctx.Value(CasbinPolicyContextKey) returns nil.
Common situations: Copying an example that only sets CasbinModelContextKey; switching from file-based policy to an adapter (e.g. SQL) and forgetting the context key still must be populated; renaming the policy file so the stored path points nowhere; test harnesses that build contexts by hand and skip the policy.
Related errors
- CasbinModel is required in context
- Unauthorized Access
- token up for parsing was not passed through the context
- JWT was invalid
- JWT is expired
AI-assisted analysis of go-kit/kit@78fbbceece (2026-08-15).
Data as JSON: /api/errors/096cb0d8cc404cbf.
Report an issue: GitHub.