conductor-oss/conductor · error · RuntimeException
Failed to generate SQS policy
Error message
Failed to generate SQS policy
What it means
Thrown by SQSObservableQueue.getPolicy when ObjectMapper.writeValueAsString fails to serialize the SqsPolicy into a JSON string. The policy is built to grant sqs:SendMessage permission to a set of AWS account IDs and is attached to the queue via setQueueAttributes. The underlying JsonProcessingException (a checked Jackson exception) is wrapped in an unchecked RuntimeException, so it propagates through code that does not declare it. It indicates the policy object graph cannot be rendered to JSON at runtime.
Source
Thrown at awssqs-event-queue/src/main/java/com/netflix/conductor/sqs/eventqueue/SQSObservableQueue.java:313
SqsPolicy policy = new SqsPolicy();
policy.setVersion("2012-10-17");
SqsStatement statement = new SqsStatement();
statement.setEffect("Allow");
statement.setAction("sqs:SendMessage");
statement.setResource(getQueueARN());
SqsPrincipal principal = new SqsPrincipal();
principal.setAws(new ArrayList<>(accountIds));
statement.setPrincipal(principal);
policy.setStatement(List.of(statement));
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(policy);
} catch (JsonProcessingException e) {
LOGGER.error("Failed to generate SQS policy for accounts: {}", accountIds, e);
throw new RuntimeException("Failed to generate SQS policy", e);
}
}
private List<String> listQueues(String queueName) {
ListQueuesRequest listQueuesRequest =
ListQueuesRequest.builder().queueNamePrefix(queueName).build();
ListQueuesResponse resultList = client.listQueues(listQueuesRequest);
return resultList.queueUrls().stream()
.filter(queueUrl -> queueUrl.contains(queueName))
.collect(Collectors.toList());
}
private void publishMessages(List<Message> messages) {
LOGGER.debug("Sending {} messages to the SQS queue: {}", messages.size(), queueName);
List<SendMessageBatchRequestEntry> entries =
messages.stream()
.map(View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Inspect the logged cause (the JsonProcessingException) to find which field of SqsPolicy/SqsStatement/SqsPrincipal cannot be serialized.
- Verify the SqsPolicy/SqsStatement/SqsPrincipal classes still have public no-arg constructors and standard getters; add @JsonIgnore to non-serializable fields or annotate the problematic property.
- If you forked or upgraded the SQS event-queue module, diff the policy DTO classes against a known-working version and restore the serializable shape.
- As a workaround, serialize with a ObjectMapper registered with a JavaTimeModule / FAIL_ON_EMPTY_BEANS disabled, but prefer fixing the DTO.
Example fix
// before ObjectMapper objectMapper = new ObjectMapper(); return objectMapper.writeValueAsString(policy); // after (defensive config; root cause is usually the DTO shape) ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); return objectMapper.writeValueAsString(policy);
Defensive patterns
Strategy: validation
Validate before calling
// Validate accountIds are well-formed AWS account IDs before building the policy
private static final java.util.regex.Pattern ACCT =
java.util.regex.Pattern.compile("^\\d{12}$");
boolean valid = accountIds != null
&& accountIds.stream().allMatch(a -> ACCT.matcher(a).matches());
if (!valid) return null; Try / catch
try {
queue.getPolicy(accountIds);
} catch (RuntimeException e) {
if (e.getCause() instanceof JsonProcessingException jpe) {
log.warn("SQS policy serialization failed; check SqsPolicy DTO: {}", jpe.getOriginalMessage());
}
throw e;
} Prevention
- Unit-test getPolicy with a realistic accountIds list so DTO regressions surface before deployment.
- Keep SqsPolicy/SqsStatement/SqsPrincipal POJOs minimal and getter-based.
- Treat RuntimeException from getPolicy as fatal — it means the policy DTO is broken, not a config issue.
When it happens
Trigger: Calling getPolicy(List<String> accountIds) with a non-null, non-empty accountIds list when the SqsPolicy/SqsStatement/SqsPrincipal model contains a field type Jackson cannot serialize (e.g. a custom type, circular reference, or missing no-arg constructor / getters). The method is invoked internally during queue initialization when the accountIds property ('conductor.event-queues.sqs.registeredAccountIds' or equivalent) is configured.
Common situations: A version change to the SqsPolicy/SqsStatement/SqsPrincipal DTO classes that breaks Jackson serialization (removed getters, added a non-serializable field). A custom/forked policy model with fields Jackson cannot introspect. Extremely unlikely from configuration alone since accountIds is plain List<String>.
Related errors
- Error serializing to json
- PLAN_EXECUTE '${config.getName()}': tool '${t.getName()}' fa
- Error preparing chat completion task input: %s
- Error communicating with S3 - operation:%s, payloadType: %s,
- Error generating presigned URL
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/050b88439c346528.
Report an issue: GitHub.