Błąd internetu

Błąd ERR_UPLOAD_STREAM_REWIND_NOT_SUPPORTED – przyczyny i naprawa

Mateusz Sobociński
Autor: Mateusz Sobociński - CEO & Red. Nacz. @ asMAX
9 min. czytania

Błąd ERRUPLOADSTREAMREWINDNOT_SUPPORTED to problem, który najczęściej występuje w aplikacjach Node.js podczas próby ponownego wysłania danych ze strumienia, który nie obsługuje operacji przewijania wstecz. Jest to szczególnie powszechne przy pracy z bibliotekami do obsługi żądań HTTP, takimi jak Axios, Request lub Got.

Czym jest ten błąd?

ERRUPLOADSTREAMREWINDNOT_SUPPORTED pojawia się, gdy aplikacja próbuje automatycznie ponowić nieudane żądanie HTTP zawierające strumień danych (stream), który został już częściowo lub całkowicie odczytany. Ponieważ strumienie w Node.js są jednorazowe i nie można ich „cofnąć” do początku, próba ponownego wysłania kończy się błędem.

Typowe scenariusze wystąpienia –

  • Przesyłanie plików przez formularze multipart/form-data
  • Automatyczne ponowne próby żądań HTTP przy błędach sieciowych
  • Przekierowania HTTP (301, 302) podczas wysyłania danych
  • Proxy i middleware przetwarzające strumienie danych

Dla Web Deweloperów

Przyczyny techniczne

Główne przyczyny tego błędu to:

Wykorzystanie strumieni Node.js w żądaniach HTTP – obiekty typu fs.createReadStream() lub inne strumienie danych nie mogą być ponownie odczytane po pierwszym użyciu.

Automatyczne mechanizmy retry – biblioteki HTTP często próbują automatycznie ponawiać nieudane żądania, co powoduje konflikt ze strumieniami.

Przekierowania HTTP – gdy serwer odpowiada kodem przekierowania podczas przesyłania strumienia, klient musi wysłać dane ponownie, co jest niemożliwe.

Rozwiązania dla Node.js i Axios

Rozwiązanie 1 – Wyłączenie automatycznych powtórzeń

const axios = require('axios'); const fs = require('fs'); const formData = new FormData(); formData.append('file', fs.createReadStream('plik.pdf')); axios.post('https://example.com/upload', formData, { maxRedirects: 0, // Wyłącz przekierowania maxContentLength: Infinity, maxBodyLength: Infinity, headers: { ...formData.getHeaders() } }) .catch(error => { console.error('Błąd:', error.message); }); 

Rozwiązanie 2 – Użycie bufora zamiast strumienia

const axios = require('axios'); const fs = require('fs'); // Wczytaj cały plik do pamięci const fileBuffer = fs.readFileSync('plik.pdf'); const formData = new FormData(); formData.append('file', fileBuffer, 'plik.pdf'); axios.post('https://example.com/upload', formData, { headers: { ...formData.getHeaders() } }); 

Rozwiązanie 3 – Implementacja własnego mechanizmu retry

const axios = require('axios'); const fs = require('fs'); async function uploadWithRetry(url, filePath, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { try { const formData = new FormData(); // Twórz nowy strumień przy każdej próbie formData.append('file', fs.createReadStream(filePath)); const response = await axios.post(url, formData, { maxRedirects: 0, headers: { ...formData.getHeaders() } }); return response.data; } catch (error) { if (attempt === maxRetries - 1) throw error; console.log(`Próba ${attempt + 1} nieudana, ponawiam...`); await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1))); } } } 

Rozwiązania dla innych bibliotek HTTP

Fetch API

const fs = require('fs'); const FormData = require('form-data'); const formData = new FormData(); const fileBuffer = fs.readFileSync('plik.pdf'); formData.append('file', fileBuffer, 'plik.pdf'); fetch('https://example.com/upload', { method: 'POST', body: formData, redirect: 'manual' // Wyłącz automatyczne przekierowania }) .then(response => response.json()) .then(data => console.log(data)); 

Request (przestarzałe, ale wciąż używane)

const request = require('request'); const fs = require('fs'); const formData = { file: { value: fs.readFileSync('plik.pdf'), options: { filename: 'plik.pdf', contentType: 'application/pdf' } } }; request.post({ url: 'https://example.com/upload', formData: formData, followRedirect: false }, (err, response, body) => { if (err) console.error(err); console.log(body); }); 

Konfiguracja po stronie serwera

Jeśli kontrolujesz serwer, możesz zapobiec problemowi poprzez:

Unikanie przekierowań podczas uploadu – upewnij się, że endpoint przyjmujący pliki nie wykonuje przekierowań HTTP.

// Express.js app.post('/upload', (req, res) => { // Nie używaj res.redirect() po otrzymaniu pliku // Zamiast tego zwróć odpowiedź bezpośrednio res.status(200).json({ success: true }); }); 

Zwiększenie limitów timeoutów – daj więcej czasu na przesłanie większych plików.

app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ limit: '50mb', extended: true })); 

Best Practices

Walidacja po stronie klienta – sprawdź rozmiar i typ pliku przed wysłaniem, aby uniknąć niepotrzebnych przesyłań.

Używaj buforów dla małych plików – pliki poniżej 10-20 MB można bezpiecznie wczytać do pamięci.

Implementuj chunked upload – dla dużych plików podziel je na mniejsze części i wysyłaj sekwencyjnie.

async function uploadInChunks(filePath, chunkSize = 1024 * 1024) { const fileSize = fs.statSync(filePath).size; const chunks = Math.ceil(fileSize / chunkSize); for (let i = 0; i < chunks; i++) { const start = i * chunkSize; const end = Math.min(start + chunkSize, fileSize); const chunk = fs.readFileSync(filePath, { start, end }); await axios.post('https://example.com/upload/chunk', { chunk: chunk.toString('base64'), index: i, total: chunks }); } } 

Dla Webmasterów

Diagnostyka problemu

Krok 1: Sprawdź logi serwera

Poszukaj wpisów zawierających:

  • ERRUPLOADSTREAMREWINDNOT_SUPPORTED
  • Kody błędów HTTP 301, 302, 307, 308
  • Timeouty podczas przesyłania plików

Krok 2: Zidentyfikuj problematyczne endpointy

Sprawdź, które ścieżki URL powodują problem:

  • Endpointy przyjmujące pliki
  • Formularze z enctype=”multipart/form-data”
  • API przyjmujące duże payloady

Krok 3: Testuj środowisko

Użyj narzędzi takich jak Postman lub curl do testowania:

curl -X POST -F "[email protected]" https://example.com/upload -v 

Szybkie naprawy bez zmiany kodu

Wyłącz przekierowania na poziomie serwera

Dla Apache (.htaccess):

# Usuń lub zakomentuj reguły przekierowujące dla endpointów upload # RewriteRule ^upload/ https://example.com/upload/ [R=301,L] 

Dla Nginx:

location /upload { # Usuń dyrektywy return 301/302 # return 301 https://example.com$request_uri; # Zamiast tego użyj proxy_pass bez przekierowań proxy_pass http://backend; } 

Zwiększ limity czasowe

Apache:

Timeout 600 ProxyTimeout 600 

Nginx:

client_body_timeout 600s; proxy_read_timeout 600s; 

Monitoring i prewencja

Skonfiguruj alerty – monitoruj logi pod kątem wystąpienia tego błędu i otrzymuj powiadomienia.

Dokumentuj endpointy – utrzymuj dokumentację API z informacjami o limitach rozmiaru plików i formatach akceptowanych danych.

Regularne testy – przeprowadzaj testy przesyłania plików różnych rozmiarów w środowisku testowym.

Dla Użytkowników Końcowych

Objawy problemu

Możesz doświadczyć tego błędu, gdy:

  • Przesyłanie pliku zatrzymuje się w połowie
  • Pojawia się komunikat o błędzie podczas uploadu
  • Strona przekierowuje podczas przesyłania pliku
  • Upload działa dla małych plików, ale nie dla dużych

Proste rozwiązania

Odśwież stronę i spróbuj ponownie – czasami problem jest tymczasowy i wynika z problemów sieciowych.

Sprawdź połączenie internetowe – niestabilne połączenie może powodować przerwy w przesyłaniu.

Zmniejsz rozmiar pliku – jeśli przesyłasz bardzo duży plik:

  • Skompresuj go (ZIP, RAR)
  • Zmniejsz rozdzielczość obrazów
  • Użyj bardziej efektywnych formatów (np. JPEG zamiast PNG dla zdjęć)

Użyj innej przeglądarki – niektóre przeglądarki lepiej radzą sobie z przesyłaniem dużych plików:

  • Chrome/Edge – zazwyczaj najbardziej stabilne
  • Firefox – dobra alternatywa
  • Safari – może mieć problemy z bardzo dużymi plikami

Wyczyść cache przeglądarki – stare dane mogą powodować konflikty:

  1. Chrome/Edge: Ctrl+Shift+Del → wybierz „Cached images and files”
  2. Firefox: Ctrl+Shift+Del → wybierz „Cache”
  3. Safari: Preferences → Privacy → Manage Website Data → Remove All

Wyłącz rozszerzenia przeglądarki – niektóre rozszerzenia mogą ingerować w proces przesyłania:

  • Blokery reklam
  • VPN
  • Menedżery pobierania

Gdy nic nie działa

Skontaktuj się z administratorem strony – zgłoś problem podając:

  • Dokładny komunikat błędu
  • Rozmiar pliku, który próbujesz przesłać
  • Przeglądarkę i system operacyjny
  • Czy problem występuje zawsze, czy sporadycznie

Użyj alternatywnych metod – jeśli to możliwe:

  • Prześlij plik przez usługi zewnętrzne (Google Drive, Dropbox) i udostępnij link
  • Podziel plik na mniejsze części
  • Skorzystaj z dedykowanych aplikacji do przesyłania plików

Najczęstsze pytania

Czy to problem po mojej stronie?

Zazwyczaj nie. Ten błąd najczęściej wynika z konfiguracji serwera lub kodu aplikacji. Jednak problemy z siecią mogą go potęgować.

Czy mogę stracić dane?

Nie, błąd występuje podczas przesyłania, więc oryginalne pliki na Twoim komputerze pozostają nietknięte.

Dlaczego działa dla małych plików?

Małe pliki przesyłają się szybko, zanim wystąpią problemy z przekierowaniami lub timeoutami. Duże pliki są bardziej podatne na przerwania.

Czy to bezpieczne próbować ponownie?

Tak, możesz bezpiecznie próbować przesłać plik wielokrotnie. Każda próba jest niezależna.

Podsumowanie

Błąd ERRUPLOADSTREAMREWINDNOT_SUPPORTED to techniczny problem związany z obsługą strumieni danych w Node.js. Dla deweloperów kluczowe jest używanie buforów zamiast strumieni lub implementacja właściwego mechanizmu ponawiania prób. Webmasterzy powinni skupić się na eliminacji przekierowań i zwiększeniu limitów czasowych. Użytkownicy końcowi mogą rozwiązać problem przez odświeżenie strony, użycie innej przeglądarki lub zmniejszenie rozmiaru plików.

Podziel się artykułem
CEO & Red. Nacz. @ asMAX
Obserwuj:
Ex-redaktor w GW (Technologie) i ex-PR w koreańskim start-upie technologicznym. Absolwent Imperial College Business School (MBA) i Politechniki Warszawskiej. Od 2025 CEO i redaktor naczelny w asMAX.
Brak komentarzy

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *