Skip to content

OpenAPI generation fails when MVC API version default is absent from @Schema allowableValues #3354

Description

@jochan-clgx

Describe the bug

When Spring MVC header-based API versioning has a default version and an
operation documents version-specific header values with
@Schema(allowableValues = ...), requesting /v3/api-docs returns HTTP 500.

SpringDoc attempts to append the configured MVC default version to the schema
enum created from the annotation. That enum is immutable, so
Schema.addEnumItemObject throws UnsupportedOperationException.

Runtime request routing works correctly. The failure occurs while generating
the OpenAPI description.

To Reproduce

  • Spring Boot: 4.1.1
  • Spring Framework: 7.0.9
  • SpringDoc module: springdoc-openapi-starter-webmvc-ui:3.0.3
  • Swagger Core annotations/models: 2.2.47 (transitive)
  • Java: 25

Configure Spring MVC API versioning:

spring:
  mvc:
    apiversion:
      use:
        header: x-api-version
      default: 2.0.0

Create an annotation for an operation that is available only in version
3.0.0:

package example;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Parameter(
    name = "x-api-version",
    in = ParameterIn.HEADER,
    schema = @Schema(
        type = "string",
        allowableValues = {"3.0.0"}
    )
)
public @interface ApiVersion3Parameter {
}

Use it on a versioned controller method:

package example;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping(value = "/hello", version = "3.0.0")
    @ApiVersion3Parameter
    public String hello() {
        return "hello";
    }
}

Request:

GET /v3/api-docs

Actual result:

HTTP 500

java.lang.UnsupportedOperationException
    at io.swagger.v3.oas.models.media.Schema.addEnumItemObject(...)
    at org.springdoc.core.service.AbstractRequestService.getHeaders(...)

The relevant merge in AbstractRequestService.getHeaders() reads the default
from versionDefaultMap and calls:

parameter.getSchema().addEnumItemObject(defaultValue);

when the annotation-derived enum does not contain the configured default.

Removing spring.mvc.apiversion.default allows /v3/api-docs to be generated.
Adding the default version to the v3 annotation's allowable values also avoids
this call, but produces incorrect documentation because the v3 operation is not
available under version 2.0.0.

Expected behavior

/v3/api-docs should return a valid OpenAPI document rather than HTTP 500.
The operation-specific supported versions should remain accurate. For the
example above, the header schema should continue to allow only 3.0.0:

{
  "name": "x-api-version",
  "in": "header",
  "schema": {
    "type": "string",
    "enum": ["3.0.0"]
  }
}

SpringDoc should avoid adding a global default to an operation whose mapping
does not support that version. If an enum needs to be augmented in other cases,
the annotation-derived values must first be copied into a mutable collection.

Screenshots

Not applicable.

Additional context

  • Related API-versioning tracking issue:
    Spring Framework 7 - API versioning support #2975
  • Related request concerning ApiVersionConfigurer defaults:
    Api Versioning. Use the default version from ApiVersionConfigurer #3159
  • The same addEnumItemObject(defaultValue) merge is still present by source
    inspection in tags v3.1.0, v3.1.1, and the main branch as of
    2026-09-11. Those versions were inspected but not executed with this
    reproducer.
  • The current workaround is to leave spring.mvc.apiversion.default unset and
    implement the fallback in a custom API version resolver. This preserves
    runtime defaulting without exposing the default to SpringDoc's merge path.
  • No existing issue matching Schema.addEnumItemObject with this API-version
    configuration was found before preparing this report.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions