Troubleshoot
Fix the problems people hit most when they start pogi or point their tools at it.
Start here: run pogi doctor
pogi doctor checks the server, Python and Node.js for Lambda, the AWS SDKs for native Lambda, Docker, *.localhost names and the local certificate authority.
pogi doctorA line that starts with ✗ is a check that failed, and the line says how to fix it. Here, the AWS SDKs that native Lambda needs are not installed, and pogi lambda-sdks installs them. Long lines run off the right edge. Scroll the block to read the rest.
✓ server at http://localhost:7644 0.1.0
✓ python3 for Python Lambdas: Python 3.9.6
✓ node for Node.js Lambdas: v25.9.0
✗ AWS SDKs for native Lambdas in ~/.pogi/lambda — run `pogi lambda-sdks` (CDK custom resources need them)
✓ Docker Desktop 29.4.1 at unix:///var/run/docker.sock (Engine API 1.54)
✓ *.localhost names resolve (pogi env --hostname aws.localhost, virtual-host S3, execute-api and lambda-url hosts)
✓ local CA ~/.pogi/certs/ca.pem
pogi: 1 check(s) need attention✓means the check passed.✗means something needs fixing.pogi doctorthen exits with status 1.·is a note, not a failure.
If the first line is ✗ server at …, pogi is not running. Start it with pogi start.
"Ready." never prints, or port 7644 is in use
-
Look at the error. If another program already uses the port, pogi stops at once:
Output pogi: listen tcp 127.0.0.1:7644: bind: address already in use -
Find out what holds the port. It is often an older pogi:
lsof -nP -iTCP:7644 -sTCP:LISTENOn Windows, use
netstat -ano | findstr :7644. -
Stop that program, or start pogi on another port and tell your tools about it:
pogi start --port 7645 eval "$(pogi env --endpoint http://localhost:7645)"Commands such as
pogi statusandpogi lsfind pogi with--endpoint, or with thePOGI_ENDPOINTvariable. -
If there is no error but
Ready.is slow, look for astartinit hook. pogi printsReady.after the hooks in<data folder>/finish. The port answers while they run. This shows a hook that has not finished:init/ start.d curl localhost:7644/_localstack/init/startResponse {"completed":false,"scripts":null}pogi waitsays the same in words:Output pogi: not ready at http://localhost:7644 after 2s: it is still starting
My CLI or SDK still reaches the real cloud
-
Check that this shell has the pogi settings:
env | grep AWS_ENDPOINT_URLNo output means they are not loaded. Each new terminal needs this once. It prints nothing:
eval "$(pogi env)"Check again:
env | grep AWS_ENDPOINT_URLOutput AWS_ENDPOINT_URL=http://localhost:7644 -
Check which account answers. pogi answers with account
000000000000unless you changed it:aws sts get-caller-identityOutput { "UserId": "000000000000", "Account": "000000000000", "Arn": "arn:aws:iam::000000000000:root" } -
Look for something that sets its own address. These win over
AWS_ENDPOINT_URL:- an
--endpoint-urlflag in a script or alias; - an
AWS_or similar variable you set earlier, one per service.ENDPOINT_ URL_ S3
With the flag, the call goes to the address in the flag. The result is an error like this one:
Output aws: [ERROR]: Could not connect to the endpoint URL: "http://localhost:3/" - an
-
To skip the environment for one command, use
pogi aws. It runs the AWS CLI with the right settings:pogi aws sts get-caller-identity
For Google Cloud and Azure tools, check env | grep -E 'EMULATOR_ in the same way.
*.localhost names don't resolve
Names such as <bucket>.aws.localhost, <api>.execute-api.localhost and <id>.lambda-url.localhost need your system to resolve every *.localhost name to your own computer. macOS does. Linux does when it runs systemd-resolved. Alpine Linux containers do not.
-
Run
pogi doctor. If names don't resolve, it prints this line:Output · *.localhost names do not resolve here (musl/Alpine, Linux without systemd-resolved): use localhost and path-style S3 -
Start pogi without
--hostname, and uselocalhost. S3 then uses path-style URLs (localhost:7644/<bucket>), which work withAWS_ENDPOINT_URLalone:pogi start eval "$(pogi env)" -
API Gateway URLs and Lambda function URLs are the names that need
*.localhost. Call a function withaws lambda invokeinstead of its URL, or run your code on a machine where the names resolve.
Docker isn't running
The core of pogi doesn't need Docker. S3, SQS, SNS, DynamoDB, Lambda in Python and Node.js and most other services run inside the pogi program.
-
Run
pogi doctor. Without a container engine it prints a note, not a failure:Output · no container engine found (only --lambda docker, RDS and ElastiCache need one): start Docker Desktop, OrbStack, Colima or Podman, or set DOCKER_HOST -
Know what changes. Services that run real software, such as databases, need Docker for that part. The API still answers, but nothing runs behind it. For example, RDS creates an instance and says
available, and pogi logs this warning:Output level=WARN msg="Docker is not available: the API works, but no database runs behind this endpoint" service=rds id=db1 -
Lambda needs Docker for runtimes other than Python and Node.js, and for container images. The call fails with a clear message. This one is for
java21:Output aws: [ERROR]: An error occurred (InvalidRuntimeException) when calling the Invoke operation (reached max retries: 2): runtime java21 needs Docker (pogi runs python* and nodejs* natively; provided.* runs natively only for binaries built for darwin/arm64) -
Start Docker Desktop, OrbStack, Colima or Podman. If your engine uses a non-default socket, set
DOCKER_HOST. Runpogi doctoragain.
Azure Storage ports 10000 to 10002 are taken
Blob, Queue and Table Storage use ports 10000, 10001 and 10002, the same as Azurite (Microsoft's storage emulator). If another program holds them, pogi still starts and prints Ready.. It logs one warning for each port it could not open:
time=2026-10-14T00:29:15.900+05:30 level=WARN msg="extra port unavailable" service=azblob port=10000 err="listen tcp 127.0.0.1:10000: bind: address already in use"
time=2026-10-14T00:29:15.900+05:30 level=WARN msg="extra port unavailable" service=azqueue port=10001 err="listen tcp 127.0.0.1:10001: bind: address already in use"
time=2026-10-14T00:29:15.900+05:30 level=WARN msg="extra port unavailable" service=aztable port=10002 err="listen tcp 127.0.0.1:10002: bind: address already in use"Everything else works. The connection string from pogi env still points at 10000 to 10002, so Azure Storage calls reach the other program instead of pogi.
-
Find the program. It is often Azurite:
lsof -nP -iTCP:10000-10002 -sTCP:LISTEN -
Stop it, then restart pogi.
My upload is refused
pogi is a local emulator for tests, so it limits uploads to 10 MB (the whole file, even when it is sent in parts). A bigger upload fails with a message like this:
pogi is a local emulator for tests, so uploads are limited to 10 MB (this one is 23 MB). Raise the limit with --max-upload-mb or server.maxUploadMB in pogi.yaml.-
Use a smaller file in your test. This is the best fix: tests rarely need big files.
-
Or raise the limit. Pass the flag, or set the key in
pogi.yaml:pogi --max-upload-mb 100pogi.yaml server: maxUploadMB: 100
Function code zips (up to 50 MB) and container image pushes are not limited by this setting.
If the error is 408 (RequestTimeout), the upload sent no data for 30 seconds. Check that your client or a proxy is not stalling.
Containers or volumes are left over
pogi stops or removes its containers when it shuts down. One that was killed (kill -9, a crash, a power cut) leaves them running. With saved state pogi stops its containers on a clean exit and starts them again next time, so you see them in docker ps -a while pogi is off.
-
See what pogi left, without deleting anything:
pogi clean --dry-run -
Delete it.
pogi cleanasks first, and spares anything a running pogi owns:pogi clean -
A start without saved state also removes the containers a crashed pogi left behind.
pogi clean keeps your saved state unless you say yes to its second question (or pass --state). It never removes the pogi network or images. See pogi clean.