{"record":{"id":"4aa298d6d01776b0","repo":"apereo/cas","slug":"unable-to-obtain-a-bucket-for","errorCode":null,"errorMessage":"Unable to obtain a bucket for [{}]","messagePattern":"Unable to obtain a bucket for \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-bucket4j-core/src/main/java/org/apereo/cas/bucket4j/consumer/DefaultBucketConsumer.java","lineNumber":34,"sourceCode":" *\n * @author Misagh Moayyed\n * @since 6.5.0\n */\n@RequiredArgsConstructor\n@Slf4j\npublic class DefaultBucketConsumer implements BucketConsumer {\n    private final CasReentrantLock lock = new CasReentrantLock();\n\n    private final BucketStore bucketStore;\n\n    private final BaseBucket4jProperties properties;\n\n    @Override\n    public BucketConsumptionResult consume(final String key) {\n        return lock.tryLock(() -> {\n            val bucket = bucketStore.obtainBucket(key);\n            if (bucket == null) {\n                LOGGER.warn(\"Unable to obtain a bucket for [{}]\", key);\n                return BucketConsumptionResult.builder().consumed(false).build();\n            }\n\n            val canProceed = FunctionUtils.doAndHandle(() -> {\n                if (properties.isBlocking()) {\n                    LOGGER.debug(\"Attempting to consume a token for the authentication attempt\");\n                    return bucket.tryConsume(1, MAX_WAIT_NANOS, BlockingStrategy.PARKING);\n                }\n                return bucket.tryConsume(1);\n            }, e -> {\n                LoggingUtils.error(LOGGER, e);\n                Thread.currentThread().interrupt();\n                return false;\n            }).get();\n\n            val headers = new LinkedHashMap<String, String>();\n            val availableTokens = bucket.getAvailableTokens();\n            if (!canProceed) {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-bucket4j-core/src/main/java/org/apereo/cas/bucket4j/consumer/DefaultBucketConsumer.java#L16-L52","documentation":"DefaultBucketConsumer.consume logs this warning when the underlying bucket4j BucketStore returns null for the given key, i.e. no rate-limit bucket could be created or retrieved. The consumption attempt is abandoned and a BucketConsumptionResult with consumed=false is returned, so the request is treated as not consuming a token.","triggerScenarios":"bucketStore.obtainBucket(key) returns null inside consume(); typically the configured bucket store cannot resolve/create a bucket for that key (store misconfiguration, empty/invalid bucket configuration, or an unsupported key).","commonSituations":"Rate-limiting misconfigured in cas.authn.throttle / bucket4j properties so no valid bucket definition exists; a distributed bucket store (Redis/Hazelcast) failing to materialize buckets; keys produced by a custom principal resolver not matching store expectations.","solutions":["Verify bucket4j rate-limit configuration (bucket capacity, refill rates) is fully defined in CAS properties.","Check the BucketStore backing (in-memory vs distributed) is correctly wired and reachable.","Inspect the key derivation: confirm the key passed to consume() is non-null and produced as expected.","Enable DEBUG logging for org.apereo.cas.bucket4j to trace bucket creation."],"exampleFix":"// before: no bucket config\ncas.authn.throttle.bucket4j.enabled=true\n// after\ncas.authn.throttle.bucket4j.enabled=true\ncas.authn.throttle.bucket4j.capacity=100\ncas.authn.throttle.bucket4j.refill-duration=PT1M","handlingStrategy":"fallback","validationCode":"// before consuming, ensure rate limiting is configured\nif (!casProperties.getAuthn().getThrottle().getBucket4j().isEnabled()) {\n  skipThrottle();\n}\nif (key == null || key.isBlank()) throw new IllegalArgumentException(\"bucket key required\");","typeGuard":null,"tryCatchPattern":"BucketConsumptionResult r = bucketConsumer.consume(key);\nif (r == null || !r.isConsumed() && r.getTokensRemaining() < 0) {\n  LOGGER.warn(\"Bucket store returned no bucket for [{}]; allowing request via fallback\", key);\n  return BucketConsumptionResult.builder().consumed(true).build();\n}","preventionTips":["Define complete bucket4j capacity/refill properties before enabling throttling.","Validate the bucket key derivation covers all requests with non-null values.","Test bucket store creation at startup with an integration smoke test.","Watch for repeated 'Unable to obtain a bucket' warnings as a config regression signal."],"tags":["bucket4j","rate-limiting","throttle"],"backgroundTag":"missing-config-value","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}