conductor-oss/conductor · error · RuntimeException
Exchange type is undefined
Error message
Exchange type is undefined
What it means
Thrown as RuntimeException by getOrCreateExchange when the 'type' argument (the AMQP exchange type: direct/fanout/topic/headers) is empty. The value comes from settings.getExchangeType(). RabbitMQ requires an exchange type at declare time, so an empty value cannot proceed.
Source
Thrown at amqp/src/main/java/com/netflix/conductor/contribs/queue/amqp/AMQPObservableQueue.java:561
settings.getExchangeType(),
settings.isDurable(),
settings.autoDelete(),
settings.getArguments());
}
private AMQP.Exchange.DeclareOk getOrCreateExchange(
ConnectionType connectionType,
String name,
final String type,
final boolean isDurable,
final boolean autoDelete,
final Map<String, Object> arguments)
throws Exception {
if (StringUtils.isEmpty(name)) {
throw new RuntimeException("Exchange name is undefined");
}
if (StringUtils.isEmpty(type)) {
throw new RuntimeException("Exchange type is undefined");
}
Channel chn = null;
try {
LOGGER.debug("Creating exchange {} of type {}", name, type);
chn =
amqpConnection.getOrCreateChannel(
connectionType, getSettings().getQueueOrExchangeName());
return chn.exchangeDeclare(name, type, isDurable, autoDelete, arguments);
} catch (final Exception e) {
LOGGER.warn("Failed to create exchange {} of type {}", name, type, e);
throw e;
} finally {
if (chn != null) {
try {
amqpConnection.returnChannel(connectionType, chn);
} catch (Exception e) {
LOGGER.error("Failed to return the channel of {}. {}", connectionType, e);
}View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Add exchangeType=topic (or direct/fanout/headers) to the amqp_exchange URI.
- Set a non-empty default conductor.workflow.event-queues.amqp.exchangeType if exchanges are used broadly.
- Validate the resolved settings.getExchangeType() before calling getOrCreateExchange.
Example fix
// before amqp_exchange:myExchange?durable=true // after amqp_exchange:myExchange?exchangeType=topic&durable=true
Defensive patterns
Strategy: validation
Validate before calling
import org.apache.commons.lang3.StringUtils;
import java.util.Set;
String exchangeType = settings.getExchangeType();
Set<String> valid = Set.of("direct", "fanout", "topic", "headers");
if (useExchange && (StringUtils.isBlank(exchangeType) || !valid.contains(exchangeType.toLowerCase()))) {
throw new IllegalStateException(
"AMQP exchangeType must be one of " + valid + "; got: " + exchangeType);
} Prevention
- Always include exchangeType= in exchange URIs or set a non-empty default property.
- Validate the exchange type against the four legal AMQP values at startup.
- Document the required param next to every amqp_exchange example.
When it happens
Trigger: An exchange-typed AMQP URI with no exchangeType query parameter and no default exchangeType configured in AMQPEventQueueProperties. getOrCreateExchange(connectionType) passes settings.getExchangeType() which resolves to empty.
Common situations: Forgetting the exchangeType= query param in the URI when the global default is unset; setting conductor.workflow.event-queues.amqp.exchangeType to blank; upgrading config where the property key changed.
Related errors
- Exchange name is undefined
- Queue name is undefined
- Queue name for publishing is undefined
- Delivery mode must be 1 or 2
- Queue URI doesn't matches the expected regexp
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/bdb5c11c93730d69.
Report an issue: GitHub.