Your CI failed this morning. The error is something like:
Error: LocalStack requires authentication. Please provide a valid auth token.
or:
localstack.exceptions.ServiceNotAvailable: The service 's3' is not available
in LocalStack Community. Please visit https://localstack.cloud for more info.
You didn't change anything. It worked last week. Here's what happened and what to do about it.
What Happened
LocalStack changed its authentication model in early 2025. Free usage now requires a free account and an auth token. Without one, the service throws authentication errors on startup — which is why your CI pipeline broke without you touching anything.
There are three things most developers don't know:
The free tier is still free. The auth token requirement was a change to the distribution model, not a paywall. You can get a free token in about 90 seconds at app.localstack.cloud.
CI credits are now unlimited. LocalStack initially announced a CI credit limit on the free tier. They reversed it. Free accounts now have no cap on CI runs. If you avoided the token route because you thought there was a credit limit, there isn't one.
There's a 12-day bypass that expires April 6. Setting
LS_ACKNOWLEDGE_ACCOUNT_REQUIREMENT=1in your environment lets you run LocalStack without auth until April 6, 2026. After that date, this workaround stops working.
With that context, here are your three options ranked by effort:
Option 1: Get a Free Auth Token (10 minutes, no code changes)
If LocalStack is serving you well and the only issue is the auth requirement:
- Create a free account at app.localstack.cloud
- Generate a token (Settings → Auth Tokens)
- Add it to CI:
GitHub Actions:
- name: Start LocalStack
uses: LocalStack/setup-localstack@v2
with:
image-tag: 'latest'
env:
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
Docker Compose:
services:
localstack:
image: localstack/localstack
environment:
- LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN}
- Add
LOCALSTACK_AUTH_TOKENas a CI secret (GitHub: Settings → Secrets and variables → Actions)
That's it. CI credits are unlimited on the free tier, so this is a permanent fix for most teams.
Use this if: You're using S3, DynamoDB, SQS, or other services that LocalStack handles well and you want the minimum-effort fix.
Option 2: The April 6 Bypass (0 minutes, temporary)
If you need CI green today while you evaluate a longer-term path:
# GitHub Actions
- name: Start LocalStack
run: docker run -d -p 4566:4566 -e LS_ACKNOWLEDGE_ACCOUNT_REQUIREMENT=1 localstack/localstack
This works until April 6, 2026. After that date, LocalStack ignores this variable and auth is required.
Use this if: You need CI unblocked right now and can address the real fix this week.
Option 3: Go Auth-Free (2-4 hours, permanent independence)
Two paths here, depending on your test type.
For unit tests: Moto
Moto is a Python library that mocks AWS services directly in your test process. No Docker, no auth, no external dependency. Tests run faster because there's no network overhead.
pip install "moto[s3,dynamodb,sqs]"
Before (LocalStack):
import boto3
import pytest
@pytest.fixture(scope="session")
def aws_endpoint():
return "http://localhost:4566"
def test_upload_file(aws_endpoint):
s3 = boto3.client("s3", endpoint_url=aws_endpoint)
s3.create_bucket(Bucket="test-bucket")
s3.put_object(Bucket="test-bucket", Key="file.txt", Body=b"hello")
obj = s3.get_object(Bucket="test-bucket", Key="file.txt")
assert obj["Body"].read() == b"hello"
After (Moto):
import boto3
import pytest
from moto import mock_aws
@pytest.fixture
def aws_credentials(monkeypatch):
monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing")
monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "testing")
monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1")
@mock_aws
def test_upload_file(aws_credentials):
s3 = boto3.client("s3")
s3.create_bucket(Bucket="test-bucket")
s3.put_object(Bucket="test-bucket", Key="file.txt", Body=b"hello")
obj = s3.get_object(Bucket="test-bucket", Key="file.txt")
assert obj["Body"].read() == b"hello"
The test logic is identical. The difference: no endpoint_url, no running Docker container, and the @mock_aws decorator handles setup and teardown.
Moto supports the services most teams actually use: S3, DynamoDB, SQS, SNS, Lambda, IAM, Secrets Manager, EC2. Full list in the Moto docs.
Use this if: Your tests check your code's logic, not AWS's behavior. Moto is faster, zero-dependency, and has no auth requirements — now or ever.
For integration tests: Floci
If your tests require a real running HTTP service on port 4566 — multi-service workflows, Terraform/CDK testing, or anything that can't be intercepted in-process — Floci is a zero-auth drop-in replacement for LocalStack Community Edition.
# GitHub Actions
- name: Start Floci
run: |
docker run -d -p 4566:4566 hectorvent/floci:latest
sleep 2 # wait for startup
Swap localstack/localstack for hectorvent/floci:latest in your Docker Compose or CI config. Same port, same endpoints, no auth token required.
Maturity caveat: Floci is a very new project — it launched March 22, 2026 (days ago, not weeks). Confirmed coverage (v1.0.5): S3, SQS, DynamoDB, RDS, ElastiCache, API Gateway v2, Cognito, IAM, STS, Kinesis, KMS — 20+ services total per project docs, but not LocalStack's full catalog. Its codebase is largely AI-assisted — validate service behavior against real AWS before relying on it for production CI. Check the Floci README for current service coverage before migrating.
Use this if: You need a running multi-service emulator with zero auth, and your tests stay within Floci's supported service set.
testcontainers-python Users: This Is for You
If you're using the testcontainers-localstack Python package, your situation is slightly different from raw Docker users — and as of March 24, 2026, the maintainer hasn't patched the library yet.
The testcontainers-python maintainer commented on March 17: "I will revisit this issue when something breaks." It broke on March 23. The library currently has no built-in mechanism to pass LOCALSTACK_AUTH_TOKEN to the container it spins up. Java, Node, and .NET testcontainers libraries have all been updated; Python has not.
Your options with testcontainers-python:
Option A — Pass the token via with_env (workaround until library is patched):
import os
import pytest
import boto3
from testcontainers.localstack import LocalStackContainer
@pytest.fixture(scope="session")
def localstack():
token = os.environ.get("LOCALSTACK_AUTH_TOKEN", "")
container = LocalStackContainer(image="localstack/localstack:latest")
if token:
container = container.with_env("LOCALSTACK_AUTH_TOKEN", token)
with container as ls:
yield ls
def test_s3_bucket(localstack):
url = localstack.get_url()
s3 = boto3.client(
"s3",
endpoint_url=url,
aws_access_key_id="test",
aws_secret_access_key="test",
region_name="us-east-1",
)
s3.create_bucket(Bucket="test-bucket")
buckets = s3.list_buckets()
assert any(b["Name"] == "test-bucket" for b in buckets["Buckets"])
Set LOCALSTACK_AUTH_TOKEN as an env var in CI (GitHub Actions: Settings → Secrets). The with_env call passes it through to the container.
Option B — Use the April 6 bypass (temporary):
container = LocalStackContainer(image="localstack/localstack:latest")
container = container.with_env("LS_ACKNOWLEDGE_ACCOUNT_REQUIREMENT", "1")
Works until April 6, 2026. After that, you'll need Option A or a library update.
Option C — Switch to Floci:
from testcontainers.core.container import DockerContainer
from testcontainers.core.waiting_utils import wait_for_logs
@pytest.fixture(scope="session")
def floci():
container = DockerContainer("hectorvent/floci:latest").with_bind_ports(4566, 4566)
with container as fc:
wait_for_logs(fc, "Ready.", timeout=30)
yield fc
No auth token needed. Uses DockerContainer directly since there's no testcontainers-floci package yet — but it's the same interface.
When Moto Isn't the Right Tool
Moto is not a drop-in for everything LocalStack does.
If you're testing multi-service workflows (S3 event triggers → Lambda → SQS), CDK/Terraform deployments, or anything that needs real HTTP endpoints across containers, you need a running service — LocalStack with a token (Option 1) or Floci (Option 3).
Moto is a mock. LocalStack and Floci are emulations. If your tests check that your code calls AWS correctly, use Moto. If your tests check that AWS behaves a certain way end-to-end, use a running emulator.
The Decision Tree
CI broken because of LocalStack auth?
│
├─ Need it working TODAY (no code changes) → Option 2 (bypass, expires April 6)
│
├─ Want permanent fix, keep using LocalStack → Option 1 (free token, ~10 min)
│
└─ Want to eliminate auth entirely → Option 3 (~2-4h)
│
├─ Unit tests (boto3 in-process) → Moto
│
└─ Integration tests (real HTTP, multi-service) → Floci
testcontainers-python? See the section above — with_env workaround works today.
The Automation Cookbook includes 30+ production-tested Python automation scripts — including AWS/boto3 patterns that work with LocalStack, Moto, and Floci, with CI YAML and test coverage included.
Top comments (0)