{"record":{"id":"41ba0fe507f77b24","repo":"conductor-oss/conductor","slug":"workflow-message-queue-for-workflowid-has-reach","errorCode":null,"errorMessage":"Workflow message queue for workflowId={} has reached the maximum size of {}","messagePattern":"Workflow message queue for workflowId=(.+?) has reached the maximum size of (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/netflix/conductor/core/dao/InMemoryWorkflowMessageQueueDAO.java","lineNumber":48,"sourceCode":" *\n * <p>Used as the default DAO when no Redis-backed implementation is available (e.g. when {@code\n * conductor.db.type} is not a Redis variant). Not durable across server restarts.\n */\npublic class InMemoryWorkflowMessageQueueDAO implements WorkflowMessageQueueDAO {\n\n    private final Map<String, Queue<WorkflowMessage>> queues = new HashMap<>();\n\n    private final int maxQueueSize;\n\n    public InMemoryWorkflowMessageQueueDAO(WorkflowMessageQueueProperties properties) {\n        this.maxQueueSize = properties.getMaxQueueSize();\n    }\n\n    @Override\n    public synchronized void push(String workflowId, WorkflowMessage message) {\n        Queue<WorkflowMessage> queue = queues.computeIfAbsent(workflowId, k -> new LinkedList<>());\n        if (queue.size() >= maxQueueSize) {\n            throw new IllegalStateException(\n                    \"Workflow message queue for workflowId=\"\n                            + workflowId\n                            + \" has reached the maximum size of \"\n                            + maxQueueSize);\n        }\n        queue.add(message);\n    }\n\n    @Override\n    public synchronized List<WorkflowMessage> pop(String workflowId, int maxCount) {\n        Queue<WorkflowMessage> queue = queues.get(workflowId);\n        if (queue == null || queue.isEmpty()) {\n            return Collections.emptyList();\n        }\n        List<WorkflowMessage> result = new ArrayList<>(maxCount);\n        for (int i = 0; i < maxCount && !queue.isEmpty(); i++) {\n            result.add(queue.poll());\n        }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/core/src/main/java/com/netflix/conductor/core/dao/InMemoryWorkflowMessageQueueDAO.java#L30-L66","documentation":"Thrown by InMemoryWorkflowMessageQueueDAO.push when the per-workflowId queue has already reached maxQueueSize. This DAO backs the per-workflow message queue with an in-memory HashMap of LinkedLists (not durable, not clustered). The bound prevents unbounded memory growth from a single workflow.","triggerScenarios":"Calling push(workflowId, message) when queues.get(workflowId).size() >= properties.getMaxQueueSize(). Fires before queue.add, so the message is rejected and the queue stays full.","commonSituations":"A workflow that consumes messages slower than they arrive (back-pressure not honored). A consumer stuck or dead, so messages accumulate. Using the in-memory DAO (default when no Redis variant) in a scenario that needs durable/scalable queuing — the bound trips quickly under load. A producer loop pushing without draining.","solutions":["Drain the queue by consuming/popping messages for that workflowId before pushing more.","Raise conductor workflow-message-queue max-queue-size if the burst is legitimate.","Switch to the Redis-backed WorkflowMessageQueueDAO for production — the in-memory impl is single-node and non-durable.","Fix a stuck consumer so the queue drains naturally.","Delete the workflowId queue (delete(workflowId)) if it is orphaned."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check queue size before pushing\nlong size = messageQueueDAO.size(workflowId);\nif (size >= maxQueueSize) {\n    // drain or back off instead of letting push throw\n    handleBackpressure(workflowId);\n}","typeGuard":null,"tryCatchPattern":"try {\n    messageQueueDAO.push(workflowId, message);\n} catch (IllegalStateException e) {\n    // queue full -> apply back-pressure: drain, raise size, or switch to durable DAO\n}","preventionTips":["Do not use the in-memory DAO for production-scale queuing; switch to the Redis-backed implementation.","Size maxQueueSize to your worst-case burst and monitor queue depth.","Ensure consumers drain queues so producers never hit the cap."],"tags":["queue","in-memory","back-pressure","configuration","workflow-message"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}