OpenFeign/feign · error · IllegalStateException

JAXBContextFactory must be non-null

Error message

JAXBContextFactory must be non-null

What it means

In the javax-based soap module, SOAPDecoder.Builder.build() throws IllegalStateException when no JAXBContextFactory has been provided, because the decoder cannot create JAXB contexts to unmarshal SOAP bodies without it.

Solutions

  1. Call .withJAXBContextFactory(jaxbFactory) before build().
  2. Construct the factory via new JAXBContextFactory.Builder().build() and store it once for encoder+decoder.
  3. Add an assertion/check in configuration code that the factory is non-null before building.

Example fix

// before
new SOAPDecoder.Builder().build()
// after
new SOAPDecoder.Builder().withJAXBContextFactory(factory).build()
Defensive patterns

Strategy: validation

Validate before calling

JAXBContextFactory factory = /* built once */;
java.util.Objects.requireNonNull(factory, "factory required before SOAPDecoder build");

Try / catch

try {
  decoder = new SOAPDecoder.Builder().withJAXBContextFactory(factory).build();
} catch (IllegalStateException e) {
  if ("JAXBContextFactory must be non-null".equals(e.getMessage())) {
    // supply factory and rebuild
  }
  throw e;
}

Prevention

When it happens

Trigger: Building a SOAPDecoder with new SOAPDecoder.Builder().build() and omitting .withJAXBContextFactory(...) during Feign client configuration.

Common situations: Missing builder step after refactoring; DI returning null factory; tutorial code trimmed the factory line.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/113e40ea2da60cce. Report an issue: GitHub.

Appendix: source

Thrown at soap/src/main/java/feign/soap/SOAPDecoder.java:178

    public Builder withSOAPProtocol(String soapProtocol) {
      this.soapProtocol = soapProtocol;
      return this;
    }

    /**
     * Alters the behavior of the code to use the {@link SOAPBody#getFirstChild()} in place of
     * {@link SOAPBody#extractContentAsDocument()}.
     *
     * @return the builder instance.
     */
    public Builder useFirstChild() {
      this.useFirstChild = true;
      return this;
    }

    public SOAPDecoder build() {
      if (jaxbContextFactory == null) {
        throw new IllegalStateException("JAXBContextFactory must be non-null");
      }
      return new SOAPDecoder(this);
    }
  }

  @Override
  public boolean canDecode(Response response, Type type) {
    return Util.isXmlContentType(response);
  }
}

View on GitHub (pinned to e2a1e27560)