Override S3 endpoint using Boto3 configuration file
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Overriding the S3 endpoint in Boto3 is useful when you want to talk to LocalStack, MinIO, Ceph, or another S3-compatible service instead of the default AWS endpoint. The most explicit way is to pass endpoint_url in code, but Boto3 and botocore can also read service endpoint overrides from the shared AWS config file. The important part is knowing which profile is active and whether the endpoint comes from config, environment, or code.
The Shared AWS Config File Matters
Boto3 reads configuration from the same shared AWS config system used by other AWS SDK tooling. The usual config file is:
Profiles in that file can contain region and service endpoint settings. A service-specific endpoint override can be modeled by attaching a services section to the profile.
Example:
Then activate the profile:
Once that profile is active, Boto3 can pick up the endpoint override from configuration rather than from hardcoded application code.
Use the Configured Profile in Boto3
A simple example looks like this:
If the shared config is set up correctly, the client uses the configured S3 endpoint automatically.
This is useful when you want the same application code to work across different environments just by switching profiles.
The Most Explicit Fallback: Pass endpoint_url in Code
Even if the question is about the config file, it is worth knowing the direct code-based equivalent because it is easier to debug and makes the active endpoint obvious.
This form wins when:
- you need one-off local testing
- you want no ambiguity about where the endpoint came from
- the environment does not support the shared config style cleanly
The shared config file is cleaner for reusable profile-based workflows. The code override is cleaner for isolated scripts and debugging.
Understand the Configuration Precedence
When endpoint behavior seems confusing, the usual reason is configuration precedence. The effective endpoint may come from:
- explicit
endpoint_urlin code - environment variables
- the shared AWS config profile
- default SDK behavior
That means an endpoint in ~/.aws/config can appear to do nothing if the application also passes endpoint_url directly.
In other words, the first debugging question should be: where is the client really getting its endpoint from?
Confirm the Effective Client Setup
A practical debugging trick is to inspect the client metadata after construction:
If this prints the expected value, the override is active. If it still shows a standard AWS S3 endpoint, then the profile is not being used as expected or another configuration source is taking precedence.
S3-Compatible Services Often Need Extra Options
Endpoint override is only part of the story when using non-AWS S3 services. Some services also expect:
- path-style addressing
- test credentials
- a specific region string
- signature compatibility choices
For example, some local emulators work more reliably with path-style addressing set through botocore config in code.
The endpoint override gets you to the right host, but the rest of the client behavior still has to match the service you are using.
Common Pitfalls
One common mistake is editing ~/.aws/config but then creating the Boto3 client with a different profile or no profile at all.
Another mistake is assuming the shared config endpoint will override an explicit endpoint_url passed in code. Direct client arguments are typically more specific, so the code path usually wins.
Developers also sometimes forget that S3-compatible services may require additional settings beyond just the endpoint, such as test credentials or path-style addressing.
Finally, always confirm the effective endpoint with s3.meta.endpoint_url instead of assuming the config file was applied correctly.
Summary
- Boto3 can use service endpoint overrides from the shared AWS config file.
- A profile can reference a
servicessection that defines the S3endpoint_url. - For debugging and one-off scripts, passing
endpoint_urldirectly in code is the clearest fallback. - The active endpoint depends on configuration precedence across code, environment, and shared config.
- Always verify the effective endpoint at runtime instead of assuming the profile was loaded.
Related reading
- Paginating a DynamoDB query in boto3
- Pagination with DynamoDBMapper Java AWS SDK
- Pagination with DynamoDBMapper Java AWS SDK
- ParameterVailidation Failed When Sending List to DynamoDB
- pandas - add new column to dataframe from dictionary
- Pandas column of lists, create a row for each list element
- Parquet Output From Kafka Connect to S3
- Parse multipart/form-data from body as string on AWS Lambda

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.