Next.js: Some images on production website get error 400, but some other pictures are loading

I finished a customer website (look at dev2.bodyharmoniewien.at) and in the treatment sections, there’s an image reel which receives the images by an array of image paths, set in a content.tsx file for each treatment.
If I run the website in development mode at localhost:3000, I can see all images.
But when I deployed the website via Docker on our production server, strangely some images are being shown, but some are not – even though they have the same paths.
All images of “HotStone” are loading (but with a suspicious delay), so does the logo-image, the hand-with-flower-image and the sample images of “Studio Niederösterreich”.

The docker-container logs show this here:

▲ Next.js 14.2.3
  - Local:        
  - Network:      
 ✓ Starting...
 ✓ Ready in 186ms
 ⨯ The requested resource isn't a valid image for /static/images/BodyClassic3.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/BodyClassic4.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/BodyClassic5.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/BodyClassic2.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/BodyClassic1.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/StudioWien4.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/StudioWien2.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/StudioWien3.jpg received text/html; charset=utf-8
 ⨯ The requested resource isn't a valid image for /static/images/StudioWien7.jpg received text/html; charset=utf-8
and so on.....

The browser console shows these errors:
Browser console errors


Here is my project directory schema:

components/
├── atoms/
│   ├── BookNowButton.tsx
│   ├── FlyingButterflyMouse.tsx
│   ├── ImageCollection.tsx
│   ├── ImageReel.tsx
│   ├── Logo.tsx
│   ├── LottieAnimation.tsx
│   ├── MarqueeElement.tsx
│   ├── MobileSnackbar.tsx
│   ├── MouseCursor.tsx
│   └── ProductListElement.tsx
├── layout/
│   ├── Credits.tsx
│   ├── DefaultSpacing.tsx
│   └── LegalMenu.tsx
├── sections/
│   ├── StudioSection.tsx
│   ├── TreatmentSectionDesktop.tsx
│   └── TreatmentSectionMobile.tsx
├── templates/
│   ├── TwoByTwo.tsx
│   └── SectionIndicator.tsx
lib/
├── config/
├── content/
│   ├── content.tsx
│   ├── helper/
│   └── models/
node_modules/
pages/
├── datenschutz/
├── impressum/
├── _app.tsx
├── _document.tsx
├── 404.tsx
└── index.tsx
public/
├── static/
│   ├── animation/
│   ├── fonts/
│   └── images/
│       ├── BodyClassic1.jpg
│       ├── BodyClassic2.jpg
│       ├── BodyClassic3.jpg
│       ├── BodyClassic4.jpg
│       ├── BodyClassic5.jpg
│       ├── BodyClassic6.jpg
│       ├── BodyHarmonieWienLogoFinal.png
│       ├── BodyHotStone1.jpg
│       ├── BodyHotStone2.jpg
│       ├── BodyHotStone3.jpg
│       ├── BodyHotStone4.jpg
│       ├── BodyHotStone5.jpg
│       ├── BodyHotStone6.jpg
│       ├── BodyHotStone7.jpg
│       ├── BodyKlang1.jpg
│       ├── BodyKlang2.jpg
│       ├── BodyKlang3.jpg
│       ├── BodyKlang4.jpg
│       ├── BodyKlang5.jpg
│       ├── BodyKlang6.jpg
│       ├── BodyTantra1.jpg
│       ├── BodyTantra2.jpg
│       ├── BodyTantra3.jpg
│       ├── BodyTantra4.jpg
│       ├── BodyTantra5.jpg
│       ├── BodyTantra6.jpg
│       ├── christian.jpg
│       ├── flowers_vertical.jpg
│       ├── StudioWien1.jpg
│       ├── StudioWien2.jpg
│       ├── StudioWien3.jpg
│       ├── StudioWien4.jpg
│       ├── StudioWien5.jpg
│       ├── StudioWien6.jpg
│       ├── StudioWien7.jpg
│       ├── StudioWien8.jpg
│       ├── sven.png
│       ├── tantracropped.jpg
│       ├── tantracropped1.jpg
│       └── white_flower.png
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── browserconfig.xml
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── mstile-150x150.png
├── robots.txt
├── safari-pinned-tab.svg
└── site.webmanifest
styles/
.dockerignore
.eslintrc.json
.gitattributes
.gitignore
.npmrc
Dockerfile
next-env.d.ts
next.config.js
package.json
pnpm-lock.yaml
postcss.config.js
README.md
tailwind.config.js
tsconfig.json

Here is the website content (content.tsx):

import {Addon, Treatment} from "@/lib/models/treatment.model";

const addonDetails: { [key: string]: Addon } = {
    Meridianstift: {text: 'Meridianstift'},
    Schröpfgläser: {text: 'Schröpfgläser'},
    BodyGun: {text: 'Body-Gun'},
    Infrarotlampe: {text: 'Infrarotlampe'},
    BioAromaöl: {
        text: 'Bio-Aromaöle',
        description: 'Wir führen ein breites Sortiment an verschiedensten Aromaölen. Frag uns vor Deiner Anwendung.'
    },
    HotBodyWachs: {
        text: 'Hot-Body-Wachs',
        description: 'Speziell erwärmtes Wachs (verschiedene Duftvarianten) wird zu Deiner Anwendung verwendet. Es bietet einen besonderen cremigen Body Feeling für Deine Haut.'
    }
};

const getAddons = (keys: string[]): Addon[] => keys.map(key => addonDetails[key]);

export const treatments: Treatment[] = [
    {
        id: '1',
        title: 'Body Classic',
        images: [
            '/static/images/BodyClassic1.jpg',
            '/static/images/BodyClassic2.jpg',
            '/static/images/BodyClassic3.jpg',
            '/static/images/BodyClassic4.jpg',
            '/static/images/BodyClassic5.jpg'
        ],
        minuteOptions: [
        ],
        addons: getAddons([
            'Meridianstift',
            'Schröpfgläser',
            'BodyGun',
            'Infrarotlampe',
            'BioAromaöl',
            'HotBodyWachs'
        ]),
        description: 'Unsere langjährige Fachkompetenz erkennt Deine Problematik und hilft durch gezielte Berührungen Blockaden zu lösen, und Dich wieder ins energetische Gleichgewicht zu führen. Der Wohlfühlfaktor steht im Gleichklang mit Deiner Behandlung. <br/><br/>Anwendung je nach gebuchter Dauer, auf Rücken, Beine, Füße, Bauch und Kopf mit Gesicht.'
    },
    {
        id: '2',
        title: 'HotStone',
        images: [
            '/static/images/BodyHotStone1.jpg',
            '/static/images/BodyHotStone2.jpg',
            '/static/images/BodyHotStone3.jpg',
            '/static/images/BodyHotStone4.jpg',
            '/static/images/BodyHotStone5.jpg',
            '/static/images/BodyHotStone6.jpg',
            '/static/images/BodyHotStone7.jpg'
        ],
        minuteOptions: [
        ],
        addons: getAddons(['Infrarotlampe', 'BioAromaöl', 'HotBodyWachs']),
        description: 'Ursprung aus dem asiatisch, pazifischen Raum. Bei der Body Hot Stone Behandlung werden abgerundete, teils ergonomisch geformte Steine aus Keramik, welche auf ca. 60 Grad erwärmt sind, wird der gesamte Körper behandelt. Verspannungen und Körperblockaden können, durch den Wärme speichernden Stein, auch gezielt platziert durch Auflegen, gelöst werden. <br/><br/>Body Hot Stone ist für jedes Alter geeignet, lediglich bei Osteoporose und Schwangerschaft ist eine Behandlung nicht zu empfehlen.'
    },
    {
        id: '3',
        title: 'Tantra',
        images: [
            '/static/images/BodyTantra1.jpg',
            '/static/images/BodyTantra2.jpg',
            '/static/images/BodyTantra3.jpg',
            '/static/images/BodyTantra4.jpg',
            '/static/images/BodyTantra5.jpg',
            '/static/images/BodyTantra6.jpg'
        ],
        minuteOptions: [
        ],
        addons: getAddons(['Infrarotlampe', 'BioAromaöl', 'HotBodyWachs']),
        description: 'Die traditionelle Tantralehre stammt aus Indien. Entwickelt und praktiziert wurde sie vor allem zwischen 300 bis 800 nach Christus.<br/><br/>Bei BodyTantra handelt es sich um eine erotische Ganzkörperanwendung. Der gesamte Body sowie die erogenen Zonen, werden durch Berührungen/Streichungen zur Tiefenentspannung geführt und bereiten in Kombination mit stimulierenden Ölen ein wahrhaft sinnliches Körpergefühl.'
    },
    {
        id: '4',
        title: 'Klang',
        images: [
            '/static/images/BodyKlang1.jpg',
            '/static/images/BodyKlang2.jpg',
            '/static/images/BodyKlang3.jpg',
            '/static/images/BodyKlang4.jpg',
            '/static/images/BodyKlang5.jpg',
            '/static/images/BodyKlang6.jpg'
        ],
        minuteOptions: [
        ],
        description: 'Tibetanische Klangschalen werden auf Deinen Body platziert. Mit einem Klöppel werden Klänge und Schwingungen an den Schalen erzeugt.<br/><br/>Body Klang Anwendung kann eine Senkung des Blutdruckes, positive Stimulierung des Immunsystems, Schmerzlinderung sowie Reduzierung von Depressionen bewirken.'
    }
];


export const studios = {
    wien: {
        title: 'Wien',
        address: '-',
        addressLink: '',
        description: 'Klein aber Fein in exklusivem Ambiente, so präsentiert sich unser Studio, eingebettet in ein Jugendstilhaus der Jahrhundertwende im schönen 19. Wiener Bezirk Döbling. Geöffnet am Dienstag, Mittwoch und Freitag von 13:00 bis 20:00 Uhr. Bitte Termin vereinbaren.',
        images: [
            '/static/images/StudioWien1.jpg',
            '/static/images/StudioWien2.jpg',
            '/static/images/StudioWien3.jpg',
            '/static/images/StudioWien4.jpg',
            '/static/images/StudioWien5.jpg',
            '/static/images/StudioWien6.jpg',
            '/static/images/StudioWien7.jpg',
            '/static/images/StudioWien8.jpg'
        ]
    },
    niederoesterreich: {
        title: 'Niederösterreich',
        address: '-',
        addressLink: '',
        description: 'Modern und elegant präsentiert sich die Räumlichkeit bei unserem Kooperationspartner Kosmetikinstitut Liliane, Pottendorf in Niederösterreich. Nur nach vorheriger Terminvereinbarung, jeweils Donnerstag und Samstag von 8:00 bis 18:00 Uhr möglich.',
        images: ['/static/images/tantracropped.jpg', '/static/images/tantracropped1.jpg']
    },
};

This is my ImageReel.tsx:

import {motion} from "framer-motion";
import Image from "next/image";

export const ImageReel = ({images, speedFactor}: { images: string[], speedFactor?: number }) => {
    return (
        <div className={'flex justify-center gap-5 max-h-[200px] overflow-hidden'}>
            <motion.div
                className={'flex'}
                initial={{translateX: '0%'}}
                animate={{
                    translateX: ['0%', '-100%'],
                    transition: {
                        repeatType: 'loop',
                        duration: 45 / speedFactor,
                        repeat: Infinity,
                        ease: 'linear'
                    }
                }}
                style={{display: 'flex', gap: '10px'}} // Gap between images
            >
                {[...images, ...images].map((image, index) => (
                    <Image
                        key={index}
                        src={image}
                        width={200}
                        height={200}
                        className={'rounded-lg'}
                        alt={'Bild'}
                        style={{
                            maxWidth: "100%",
                            height: "auto",
                            objectFit: "cover"
                        }}
                    />
                ))}
            </motion.div>
        </div>
    );
};

My package.json:

{
  "name": "body-harmony-website",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint --fix"
  },
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^6.5.2",
    "@fortawesome/free-brands-svg-icons": "^6.5.2",
    "@fortawesome/pro-light-svg-icons": "^6.5.2",
    "@fortawesome/pro-regular-svg-icons": "^6.5.2",
    "@fortawesome/pro-solid-svg-icons": "^6.5.2",
    "@fortawesome/react-fontawesome": "^0.2.2",
    "@tailwindcss/typography": "^0.5.13",
    "axios": "^1.7.2",
    "framer-motion": "^11.2.10",
    "interweave": "^13.1.0",
    "interweave-ssr": "^2.0.0",
    "lottie-web": "^5.12.2",
    "lucide-react": "^0.390.0",
    "next": "^14.2.3",
    "next-i18next": "^15.3.0",
    "next-seo": "^6.5.0",
    "postcss": "^8.4.38",
    "react": "18.3.1",
    "react-dom": "18.3.1",
    "react-lottie": "^1.2.4",
    "react-swipeable": "^7.0.1",
    "sharp": "^0.33.4",
    "swr": "^2.2.5",
    "tailwindcss": "^3.4.4"
  },
  "devDependencies": {
    "@types/node": "^20.14.2",
    "@types/react": "18.3.3",
    "@types/react-dom": "^18.3.0",
    "@types/react-lottie": "^1.2.10",
    "autoprefixer": "10.4.19",
    "eslint": "9.4.0",
    "eslint-config-next": "14.2.3",
    "typescript": "5.4.5"
  }
}


My next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
    reactStrictMode: true,
    swcMinify: true,
    images: {
        remotePatterns: [
            {
                protocol: 'https',
                hostname: '**.bodyharmoniewien.at',
                port: '',
                pathname: '**'
            }
        ],
    },
    output: 'standalone',
    async headers() {
        return [
            {
                source: '/(.*)',
                headers: securityHeaders
            }
        ];
    }
}


const ContentSecurityPolicy = `
    default-src 'self';
    script-src 'unsafe-eval' 'unsafe-inline' 'self';
    style-src 'self' 'unsafe-inline';
    img-src * blob: data: 'self' https:;
    media-src 'self';
    connect-src *;
    worker-src 'self' blob:;
    font-src 'self' data:;
`;

const securityHeaders = [
    {
        key: 'Content-Security-Policy',
        value: ContentSecurityPolicy.replace(/n/g, '')
    },
    {
        key: 'Referrer-Policy',
        value: 'strict-origin-when-cross-origin'
    },
    {
        key: 'X-Frame-Options',
        value: 'DENY'
    },
    {
        key: 'X-Content-Type-Options',
        value: 'nosniff'
    },
    {
        key: 'X-DNS-Prefetch-Control',
        value: 'on'
    },
    {
        key: 'Strict-Transport-Security',
        value: 'max-age=31536000; includeSubDomains; preload'
    },
    {
        key: 'Permissions-Policy',
        value: 'camera=(), microphone=(), geolocation=()'
    }
];

module.exports = nextConfig

I was already checking all paths, syntax, image filenames, next.config.js file, Dockerfile, asked ChatGPT and searched Google for possible solutions, but it seems that yet nobody experienced the issue I have.
I have a thought that maybe it has something to do with the image array and that I am not doing an “import” for every single image. But this still does not explain why all images of “HotStone” treatment are showing up then.

New contributor

jasonschell is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật