{"record":{"id":"2f46fa4f31017558","repo":"abpframework/abp","slug":"expected-dapr-app-api-token-is-not-provided-dapr","errorCode":null,"errorMessage":"Expected Dapr App API Token is not provided! Dapr should set the 'dapr-api-token' HTTP header.","messagePattern":"Expected Dapr App API Token is not provided! Dapr should set the 'dapr-api-token' HTTP header\\.","errorType":"http","errorClass":"AbpAuthorizationException","httpStatus":403,"severity":"error","filePath":"framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs","lineNumber":31,"sourceCode":"    protected HttpContext HttpContext => GetHttpContext();\n\n    public DaprAppApiTokenValidator(IHttpContextAccessor httpContextAccessor)\n    {\n        HttpContextAccessor = httpContextAccessor;\n    }\n\n    public virtual void CheckDaprAppApiToken()\n    {\n        var expectedAppApiToken = GetConfiguredAppApiTokenOrNull();\n        if (expectedAppApiToken.IsNullOrWhiteSpace())\n        {\n            return;\n        }\n\n        var headerAppApiToken = GetDaprAppApiTokenOrNull();\n        if (headerAppApiToken.IsNullOrWhiteSpace())\n        {\n            throw new AbpAuthorizationException(\"Expected Dapr App API Token is not provided! Dapr should set the 'dapr-api-token' HTTP header.\");\n        }\n\n        if (expectedAppApiToken != headerAppApiToken)\n        {\n            throw new AbpAuthorizationException(\"The Dapr App API Token (provided in the 'dapr-api-token' HTTP header) doesn't match the expected value!\");\n        }\n    }\n\n    public virtual bool IsValidDaprAppApiToken()\n    {\n        var expectedAppApiToken = GetConfiguredAppApiTokenOrNull();\n        if (expectedAppApiToken.IsNullOrWhiteSpace())\n        {\n            return true;\n        }\n\n        var headerAppApiToken = GetDaprAppApiTokenOrNull();\n        return expectedAppApiToken == headerAppApiToken;","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs#L13-L49","documentation":"Thrown by DaprAppApiTokenValidator.CheckDaprAppApiToken when an App API token is configured on the host (IDaprApiTokenProvider.GetAppApiToken returns a non-empty value) but the incoming HTTP request has no 'dapr-api-token' header. ABP uses this to guarantee that a request to a Dapr-invoked endpoint actually originated from the Dapr sidecar, which injects the header when 'app-api-token' is set in Dapr config.","triggerScenarios":"Calling CheckDaprAppApiToken() (directly or via a Dapr endpoint filter) on a request whose 'dapr-api-token' header is absent, while AbpDaprOptions.AppApiToken / the configured token is non-empty.","commonSituations":"Configuring AppApiToken in the host but forgetting to set the matching 'app-api-token' secret in Dapr's config; Dapr sidecar restarted without the token annotation; a non-Dapr client (browser, curl, integration test) hitting the endpoint directly; token rotation where only one side was updated.","solutions":["Set the 'app-api-token' secret / '--app-api-token' flag on the Dapr sidecar so it sends the matching 'dapr-api-token' header.","Ensure the token value in Dapr config equals the AppApiToken configured in the ABP host (IDaprApiTokenProvider / AbpDaprOptions).","During local development, temporarily remove the AppApiToken config so CheckDaprAppApiToken short-circuits and returns.","If calling the endpoint outside Dapr, add the 'dapr-api-token' header manually with the configured value."],"exampleFix":"// before: host has AppApiToken set, but request lacks the header\n//  -> AbpAuthorizationException: Expected Dapr App API Token is not provided!\n\n// after: configure the Dapr sidecar secret\ndapr run --app-id myapp --app-api-token $APP_API_TOKEN -- ...\n// and in host config set the same value:\n// \"Dapr\": { \"AppApiToken\": \"<same value>\" }","handlingStrategy":"validation","validationCode":"// Before relying on the endpoint, ensure the token is set on both sides.\nvar configured = daprApiTokenProvider.GetAppApiToken();\nvar header = httpContext.Request.Headers[\"dapr-api-token\"];\nif (!string.IsNullOrEmpty(configured) && string.IsNullOrEmpty(header))\n{\n    // caller must add the header; reject/401 early with guidance\n}","typeGuard":"null","tryCatchPattern":"try { daprAppApiTokenValidator.CheckDaprAppApiToken(); }\ncatch (AbpAuthorizationException ex) when (ex.Message.Contains(\"not provided\"))\n{ /* return 401 / instruct caller to send dapr-api-token */ }","preventionTips":["Configure the matching 'app-api-token' on the Dapr sidecar whenever you set AppApiToken in the host.","Keep the token in a single secret store referenced by both sides.","In local dev, leave AppApiToken unset to bypass validation.","Automate syncing the token on rotation (CI/CD)."],"tags":["dapr","authentication","security","configuration","header"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}