Skip to content

IDE false-positive warnings for custom properties in application.properties #182

Description

@cuioss-oliver

Summary

IntelliJ IDEA (with Quarkus Tools plugin) reports false-positive "Unrecognized property" warnings and a Duration parse error for the majority of OAuth Sheriff's custom configuration properties in application.properties. These are IDE tooling limitations, not actual bugs — all properties work correctly at runtime.

This issue documents the root cause analysis, affected properties, and potential long-term remediation options.

Affected Properties

Custom sheriff.oauth.* properties (Unrecognized property)

sheriff.oauth.issuers.<name>.issuer-identifier
sheriff.oauth.issuers.<name>.enabled
sheriff.oauth.issuers.<name>.jwks.file-path
sheriff.oauth.issuers.<name>.jwks.http.well-known-url
sheriff.oauth.issuers.<name>.jwks.http.url
sheriff.oauth.issuers.<name>.jwks.http.refresh-interval-seconds
sheriff.oauth.issuers.<name>.expected-client-id
sheriff.oauth.issuers.<name>.claim-sub-optional
sheriff.oauth.health.enabled
sheriff.oauth.health.jwks.cache-seconds
sheriff.oauth.health.jwks.timeout-seconds
sheriff.oauth.metrics.collection.interval
sheriff.oauth.cache.access-token.max-size
sheriff.oauth.cache.access-token.eviction-interval-seconds

Custom cui.* properties (Unrecognized property)

cui.http.access-log.filter.enabled
cui.http.access-log.filter.min-status-code
cui.http.access-log.filter.max-status-code

Standard Quarkus properties (Unrecognized property)

quarkus.tls.default.trust-store.p12.path
quarkus.tls.default.trust-store.p12.password

Duration parse error

quarkus.virtual-threads.shutdown-timeout=10s
→ Error: "Text cannot be parsed to a Duration"

Root Cause Analysis

How IntelliJ Discovers Quarkus Properties

IntelliJ's Quarkus plugin (built on the MicroProfile Language Server / LSP4MP) scans the project classpath for properties declared via specific annotations:

Declaration Method IDE Recognition Used by OAuth Sheriff
@ConfigRoot + @ConfigMapping interface Yes — metadata generated by annotation processor No
@ConfigProperty CDI injection Yes — language server detects injection points Only 1 property (health.jwks.cache-seconds)
Programmatic Config API (config.getOptionalValue(key, type)) No — runtime string lookups cannot be statically analyzed Yes — all other properties

Why Our Properties Are Not Recognized

OAuth Sheriff reads nearly all configuration properties via manual resolver classes that use the Eclipse MicroProfile Config API programmatically:

// IssuerConfigResolver.java — typical consumption pattern
Optional<String> issuerIdentifier = config.getOptionalValue(
    JwtPropertyKeys.ISSUERS.ISSUER_IDENTIFIER.formatted(issuerName),
    String.class
);

Resolver classes using this pattern:

  • IssuerConfigResolver — all sheriff.oauth.issuers.* properties
  • AccessTokenCacheConfigResolversheriff.oauth.cache.access-token.* properties
  • AccessLogFilterConfigResolvercui.http.access-log.filter.* properties
  • ParserConfigResolversheriff.oauth.parser.* properties
  • ClaimMapperRegistrysheriff.oauth.keycloak.* properties

The IDE has no metadata to validate these properties because there are:

  • No @ConfigRoot or @ConfigMapping classes
  • No config metadata artifact generated at build time
  • No equivalent of Spring Boot's additional-spring-configuration-metadata.json

Why quarkus.tls.* Properties Are Not Recognized

The quarkus-tls-registry extension properties may not be on the annotation-processing classpath of the integration-tests module if IntelliJ resolves only direct dependencies rather than transitive deployment JARs.

Why the Duration Parse Error Occurs

Quarkus uses its own DurationConverter (io.quarkus.runtime.configuration.DurationConverter) that accepts shorthand formats by prepending PT:

Input Converter Action Result
10s Prepends PTPT10S Duration.ofSeconds(10)
5m Prepends PTPT5M Duration.ofMinutes(5)
2h Prepends PTPT2H Duration.ofHours(2)
PT10S ISO-8601 passthrough Duration.ofSeconds(10)

IntelliJ's MicroProfile language server validates Duration values using java.time.Duration.parse() directly, which requires ISO-8601 format (PT10S). The shorthand 10s is valid at Quarkus runtime but fails IDE validation.

Classification

Warning Category Root Cause Severity
sheriff.oauth.* unrecognized Programmatic Config API — invisible to IDE False positive
cui.http.* unrecognized Programmatic Config API — invisible to IDE False positive
quarkus.tls.* unrecognized Missing deployment JAR on IDE annotation classpath False positive
Duration parse 10s IDE uses Duration.parse() instead of Quarkus DurationConverter False positive

All properties work correctly at runtime. This is purely an IDE tooling limitation.

Potential Remediation Options

Option 1: Accept and Document (current approach)

  • Warnings are cosmetic and do not affect builds or runtime
  • Document that these are known false positives
  • Developers can suppress in IntelliJ: Preferences > Editor > Inspections > MicroProfile > Properties files

Option 2: Migrate to @ConfigMapping Interfaces (significant effort)

Refactor resolver classes to use Quarkus @ConfigMapping interfaces:

@ConfigMapping(prefix = "sheriff.oauth")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface OAuthSheriffConfig {
    @WithName("issuers")
    Map<String, IssuerConfig> issuers();
    // ...
}

Trade-offs:

  • (+) Full IDE autocompletion, validation, and navigation
  • (+) Type-safe configuration
  • (-) Significant refactoring of the entire configuration resolver architecture
  • (-) The current programmatic approach supports dynamic issuer discovery via config.getPropertyNames() to find all sheriff.oauth.issuers.<name>.* groups — @ConfigMapping with Map<String, ...> handles this differently
  • (-) Loss of fine-grained control over default value handling and validation

Option 3: Wait for Quarkus Config Metadata Support (upstream)

The Quarkus team is actively working on adopting Spring Boot's config metadata format:

When available, this would allow declaring custom property metadata without migrating to @ConfigMapping.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions