Skip to content

Fix S3 settings configuration priorities#100975

Open
alexey-milovidov wants to merge 16 commits intomasterfrom
fix-s3-settings-priority
Open

Fix S3 settings configuration priorities#100975
alexey-milovidov wants to merge 16 commits intomasterfrom
fix-s3-settings-priority

Conversation

@alexey-milovidov
Copy link
Copy Markdown
Member

Fix the priority order for S3 settings to be:

  1. Global <s3> config section (lowest priority)
  2. <storage_configuration> disk settings
  3. Table-level, user profile, and query-level settings (highest priority)

Two bugs were present:

In S3ObjectStorage::applyNewSettings, endpoint settings from the global <s3> section were applied after disk config settings, overriding them. Swapped the order so disk config takes priority over global <s3>.

In StorageS3 configuration (fromAST), endpoint settings from the global <s3> section were applied last without re-applying profile/query settings on top. Added updateFromSettings after endpoint application so that user/profile/query-level settings retain highest priority.

Closes: #50029

Changelog category (leave one):

  • Bug Fix (user-visible misbehavior in an official stable release)

Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):

Fix S3 settings priority so that storage_configuration disk settings override global <s3> section, and user/profile/query-level settings override both.

Documentation entry for user-facing changes

  • Documentation is written (mandatory for new features)

Fix the priority order for S3 settings to be:
1. Global `<s3>` config section (lowest priority)
2. `<storage_configuration>` disk settings
3. Table-level, user profile, and query-level settings (highest priority)

Two bugs were present:

In `S3ObjectStorage::applyNewSettings`, endpoint settings from the global
`<s3>` section were applied after disk config settings, overriding them.
Swapped the order so disk config takes priority over global `<s3>`.

In `StorageS3` configuration (`fromAST`), endpoint settings from the global
`<s3>` section were applied last without re-applying profile/query settings
on top. Added `updateFromSettings` after endpoint application so that
user/profile/query-level settings retain highest priority.

Closes: #50029

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@clickhouse-gh
Copy link
Copy Markdown
Contributor

clickhouse-gh bot commented Mar 27, 2026

Workflow [PR], commit [715b4c5]

Summary:

job_name test_name status info comment
Stateless tests (arm_asan_ubsan, targeted) failure
04070_s3_disk_settings_override FAIL cidb
03758_fix_isssue_87414 FAIL cidb
Stateless tests (amd_asan_ubsan, flaky check) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
40 more test cases not shown
Stateless tests (amd_tsan, flaky check) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
40 more test cases not shown
Stateless tests (amd_msan, flaky check) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
40 more test cases not shown
Stateless tests (amd_debug, flaky check) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
40 more test cases not shown
Stateless tests (amd_binary, flaky check) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
40 more test cases not shown
Stateless tests (amd_asan_ubsan, distributed plan, parallel, 1/2) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
Stateless tests (amd_debug, parallel) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
Stateless tests (amd_tsan, parallel, 1/2) failure
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
04070_s3_disk_settings_override FAIL cidb
Stateless tests (amd_tsan, parallel, 2/2) failure
03994_map_subcolumns_small_wide FAIL cidb

AI Review

Summary

This PR fixes S3 settings precedence by reordering merges in S3ObjectStorage::applyNewSettings and re-applying request settings in S3StorageParsedArguments::fromAST, then adds a DiskS3 regression test. The core fix looks correct, but coverage is still incomplete because the PR also changes the fromAST precedence path and its dedicated regression test was removed.

Findings
  • ⚠️ Majors
    • [src/Storages/ObjectStorage/S3/Configuration.cpp:618] fromAST precedence behavior changed, but there is no remaining direct regression test for this path after removing 04065_s3_settings_query_override. This leaves the updated fromAST merge order vulnerable to silent regressions.
    • Suggested fix: add a targeted test that exercises S3StorageParsedArguments settings precedence on a path not masked by writeObject re-application.
Tests
  • ⚠️ Add a regression test specifically for the fromAST precedence path (s3(...) parsing or another direct consumer), because current coverage validates only DiskS3/applyNewSettings via SYSTEM RELOAD CONFIG.
ClickHouse Rules
Item Status Notes
Deletion logging
Serialization versioning
Core-area scrutiny ⚠️ fromAST precedence path changed without direct remaining regression coverage
No test removal ⚠️ A newly added path-specific regression test was removed, leaving changed logic without direct test
Experimental gate
No magic constants
Backward compatibility
SettingsChangesHistory.cpp
PR metadata quality
Safe rollout
Compilation time
Final Verdict
  • Status: ⚠️ Request changes
  • Minimum required actions:
    • Add one direct regression test for the fromAST settings precedence path changed in this PR.

@clickhouse-gh clickhouse-gh bot added the pr-bugfix Pull request with bugfix, not backported by default label Mar 27, 2026
}

/// Re-apply user/profile/query-level settings on top, so they take priority over the global <s3> config section.
s3_settings->request_settings.updateFromSettings(context->getSettingsRef(), /* if_changed */ true);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updateFromSettings is called here with the default validate_settings=true, so this path now validates upload settings unconditionally.

That changes behavior when s3_validate_request_settings=0: before this patch, validation was gated by that setting (loadFromConfigForObjectStorage(..., validate_settings) and the final conditional validateUploadSettings), but now invalid s3_* request settings can still throw here even when validation is explicitly disabled.

Please pass the setting explicitly, e.g.:

s3_settings->request_settings.updateFromSettings(
    context->getSettingsRef(),
    /* if_changed */ true,
    context->getSettingsRef()[Setting::s3_validate_request_settings]);

alexey-milovidov and others added 5 commits March 28, 2026 02:15
…tings`

Without this, the re-applied `updateFromSettings` call would unconditionally
validate upload settings, breaking the `s3_validate_request_settings = 0` path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verifies that query-level SETTINGS (e.g., `s3_max_single_part_upload_size`)
properly override session-level defaults when using the `s3()` table function.
This exercises the `fromAST` code path where user/query-level settings must
take priority over global `<s3>` endpoint configuration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
modified_settings->request_settings.proxy_resolver = DB::ProxyConfigurationResolverProvider::getFromOldSettingsFormat(
ProxyConfiguration::protocolFromString(uri.uri.getScheme()), config_prefix, config);

/// Apply global <s3> endpoint settings first (lowest priority).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing the priority order here. Please also add a regression test for the DiskS3 path (S3ObjectStorage::applyNewSettings) in addition to the new fromAST test.

This PR fixes two independent paths, but 04065_s3_settings_query_override covers only s3 table function parsing. Without a DiskS3/reload test, the storage_configuration vs global <s3> precedence can regress silently.

The test `04065_s3_settings_query_override` was passing on master because
no global `<s3>` endpoint config existed with `max_single_part_upload_size`
set. Without such config, the bug (endpoint settings overriding query-level
settings) could not manifest.

Add `tests/config/config.d/s3_settings_override.xml` with a matching
endpoint that sets `max_single_part_upload_size` to 100Mi. Now on master
the endpoint config overrides the query-level setting (10000) causing
single-part upload, while with the fix the query-level setting is
properly re-applied after endpoint config.

Also remove the now-redundant session-level SET and update comments.

https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=100975&sha=7a6d5529ced899cb58397d66d36420a5d03fad43&name_0=PR&name_1=Bugfix%20validation%20%28functional%20tests%29

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@clickhouse-gh
Copy link
Copy Markdown
Contributor

clickhouse-gh bot commented Mar 29, 2026

LLVM Coverage Report

Metric Baseline Current Δ
Lines 84.20% 84.10% -0.10%
Functions 24.60% 24.50% -0.10%
Branches 76.70% 76.70% +0.00%

Changed lines: 100.00% (23/23) · Uncovered code

Full report · Diff report

alexey-milovidov and others added 8 commits March 29, 2026 19:47
Add `04068_s3_disk_settings_override` test that covers the
`S3ObjectStorage::applyNewSettings` code path. The test creates a table
on an S3 disk configured with a small `max_single_part_upload_size`, while
a global `<s3>` endpoint section sets a large value for the same endpoint.
The test verifies that multipart upload is used, confirming that disk config
takes priority over global `<s3>` settings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…st config

These config files were created but never symlinked in `install.sh`,
causing bugfix validation to fail (the test passed on master because
the global `<s3>` endpoint config was not loaded).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…efix

The `loadFromConfigForObjectStorage` passes `"s3_"` as the setting name
prefix when constructing `S3RequestSettings`, so disk config keys must
use the `s3_` prefix (e.g. `s3_max_single_part_upload_size`) to be
recognized. Without the prefix, the setting was silently ignored and
the global `<s3>` endpoint value took precedence, causing the test to
output `0 0 0` instead of `1 1 1`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…070` to avoid number conflict

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…le test

The bugfix validation failed because both tests passed on the old binary
("Failed to reproduce the bug"):

- Test `04070_s3_disk_settings_override` passed because
  `S3ObjectStorage::applyNewSettings` is only called during config reload,
  not during initial disk creation.  Adding `SYSTEM RELOAD CONFIG` before
  the INSERT triggers `applyNewSettings`, which on the old code applies
  the global endpoint's 100 Mi `max_single_part_upload_size` AFTER the
  disk config's 10 000 value, overriding it.  With the fix, the disk
  config takes priority.

- Test `04065_s3_settings_query_override` passed because
  `S3ObjectStorage::writeObject` independently re-applies query-level
  settings via `updateFromSettings`, compensating for the `fromAST` bug.
  Since this test cannot demonstrate the bug through the write path,
  remove it.  The `fromAST` fix remains correct as defense-in-depth for
  code paths that read the settings without the `writeObject` override
  (e.g. reads, copies).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
}

/// Re-apply user/profile/query-level settings on top, so they take priority over the global <s3> config section.
s3_settings->request_settings.updateFromSettings(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ This PR still changes the fromAST precedence path (updateFromSettings re-application), but the only remaining regression test (04070_s3_disk_settings_override) exercises DiskS3/applyNewSettings after SYSTEM RELOAD CONFIG. The earlier fromAST test was removed, so this path now has no direct regression coverage.

Please add a targeted test for the s3(...) parsing path (or another call path that consumes S3StorageParsedArguments request settings without writeObject re-applying settings), so future precedence regressions in Configuration::fromAST are caught.

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

Labels

pr-bugfix Pull request with bugfix, not backported by default

Projects

None yet

Development

Successfully merging this pull request may close these issues.

It is impossible to override global setting in special section '<clickhouse> <s3>'.

1 participant