missing Location in call to Date
panic: time: missing Location in call to Time.In
goroutine 1 [running]:
time.Time.In(...)
/usr/local/go/src/time/time.go:1146
main.main()
/app/main.go:16 +0x1c5
Does your code look somewhat like this?
location, _ := time.LoadLocation("Europe/Amsterdam")
name, offset := time.Now().In(location).Zone()
log.Println("name: "+name, "offset: "+strconv.Itoa(offset))
Are you using
Alpine
or a similar distribution in your Docker container?
Are you using a multistep Dockerfile build process?
Alpine does not contain timezone data inside the distribution. This means, the
time.LoadLocation
returns a nil for loading the location, leading to the panic at
time.Now().In
.
The Solution
At first, I suggest changing the code in a way that the error is getting caught.
location, err := time.LoadLocation("Europe/Amsterdam")
if err != nil {
log.Fatal(err)
Next, there are at least two solutions. Either add the timezone info into the distribution or use a base image that has timezone info.
1. Add timezone info
The solution is to add the timezone info in your Docker build step. But let’s clarify first why this helps.
The Go runtime checks a couple of locations for timezone information. You can read more about the exact behaviour in the
Golang LoadLocation documentation
Essentially, there are 4 locations that are checked in order:
the directory or uncompressed zip file named by the ZONEINFO environment variable
on a Unix system, the system standard installation location
$GOROOT/lib/time/zoneinfo.zip
the time/tzdata package, if it was imported
We can see that the Go distribution contains timezone info, we can copy that and reference it via an environment variable.
The following code assumes that the first step in your Docker file is called
builder
. Please change the base step name accordingly.
Add these lines to your Dockerfile:
# Copy timezone from Golang base image
COPY --from=builder /usr/local/go/lib/time/zoneinfo.zip /
# Specify timezone info location for Go application
ENV ZONEINFO=/zoneinfo.zip
Your Dockerfile might look like this in the end:
# Build stage
FROM golang:1.22 as builder
# Install musl-dev and gcc for Alpine compatibility
RUN apt-get update && apt-get install -y musl-dev musl-tools gcc
# Set the Current Working Directory inside the container
WORKDIR /app
# Copy go.mod and go.sum files
COPY go.mod go.sum ./
# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download
# Copy the source code into the container
COPY . .
# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o application .
## Final stage
FROM alpine:latest as final
## Install necessary packages, e.g. ca-certificates, if your application needs it
RUN apk --no-cache add ca-certificates
WORKDIR /app
## Copy the pre-built binary file from the previous stage
COPY --from=builder /app/application /app/application
COPY --from=builder /usr/local/go/lib/time/zoneinfo.zip /
ENV ZONEINFO=/zoneinfo.zip
CMD ["/app/application"]
2. Use different base image
In case the timezone info does not work for you, you might want try using a different base image like Ubuntu.
Keep in mind that this will result in larger final image sizes.
Further Reading
Golang Zoneinfo
Golang LoadLocation()