Skip to content

AwsS3EnvironmentRepository returns PropertySources in incorrect precedence order for multiple profiles #3271

Description

@sqiao97

Describe the bug

AwsS3EnvironmentRepository appears to return PropertySources in the wrong precedence order when multiple profiles are requested.

According to the Spring Cloud Config documentation:

Active profiles take precedence over defaults, and, if there are multiple profiles, the last one wins.

The documentation also states that higher-precedence property sources should appear earlier in the returned Environment.

For example, given the profiles:

default,dev,ap-southeast-1

the expected precedence is:

ap-southeast-1 > dev > default

However, AwsS3EnvironmentRepository returns the property sources in the same order as the requested profiles:

default
dev
ap-southeast-1

Since property sources listed earlier in the Environment have higher precedence, this effectively gives default the highest precedence, which is the opposite of the documented profile precedence.

Version

Observed with:

Spring Cloud: 2023.0.0
Spring Cloud Config Server: 4.1.0
Backend: AwsS3EnvironmentRepository

Steps to reproduce

Assume the following S3 configuration files:

# demo-service-default.yml
test:
  value: default
# demo-service-dev.yml
test:
  value: dev
# demo-service-ap-southeast-1.yml
test:
  value: regional

Request the Config Server environment using multiple profiles:

GET /demo-service/default,dev,ap-southeast-1

The returned Environment.propertySources are ordered like this:

s3:demo-service-default
s3:demo-service-dev
s3:demo-service-ap-southeast-1

Actual behavior

The returned order is:

default
dev
ap-southeast-1

Because the first PropertySource has the highest precedence, the effective precedence becomes:

default > dev > ap-southeast-1

For a property defined in all three profiles, the default value wins.

Expected behavior

Based on Spring Cloud Config's documented profile precedence, the last active profile should have the highest precedence.

Therefore, for:

default,dev,ap-southeast-1

the expected PropertySource order should be:

s3:demo-service-ap-southeast-1
s3:demo-service-dev
s3:demo-service-default

and the effective precedence should be:

ap-southeast-1 > dev > default

so that:

test.value = regional

Additional context

This issue became visible to us after upgrading a Quarkus application.

Prior to Quarkus 3.32.0, quarkus-spring-cloud-config-client requested each active profile separately and represented the returned values as profile-specific SmallRye Config properties. As a result, the Config Server's ordering across multiple profiles was not used to determine the final value.

Starting with Quarkus 3.32.0, the client behavior was intentionally changed to send all profiles in a single Spring Cloud Config request, matching the behavior of the standard Spring Cloud Config client:

/demo-service/default,dev,ap-southeast-1

Relevant Quarkus change:

quarkusio/quarkus#52435

This caused the ordering returned by AwsS3EnvironmentRepository to directly affect configuration precedence and exposed the issue.

Reversing the profiles in the request confirms that this is an ordering issue.

For example:

GET /demo-service/ap-southeast-1,dev,default

causes the S3 repository to return:

s3:demo-service-ap-southeast-1
s3:demo-service-dev
s3:demo-service-default

and the regional configuration then correctly wins.

Why this appears inconsistent

The documented Spring Cloud Config behavior is:

profiles = default,dev,ap-southeast-1

precedence:
ap-southeast-1 > dev > default

but AwsS3EnvironmentRepository appears to preserve the incoming profile iteration order when constructing the Environment:

default
dev
ap-southeast-1

Since higher precedence corresponds to appearing earlier in Environment.propertySources, preserving the incoming profile order reverses the intended profile precedence.

Documentation reference

Spring Cloud Config Environment Repository documentation:

https://docs.spring.io/spring-cloud-config/reference/server/environment-repository.html

Relevant documented behavior:

  • Active profiles take precedence over defaults.
  • If there are multiple profiles, the last one wins.
  • Higher precedence translates to a PropertySource listed earlier in the Environment.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions