# FMOD Core (iOS) HTTPS internet streaming fails

**URL:** <https://qa.fmod.com/t/fmod-core-ios-https-internet-streaming-fails/24550>\
**Category:** FMOD Engine\
**Created:** [October 6, 2026, 11:53am UTC](https://qa.fmod.com/t/fmod-core-ios-https-internet-streaming-fails/24550 "2026-10-06T11:53:50Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![joshechoes](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/joshechoes/32/558_2.png) [@joshechoes](https://qa.fmod.com/u/joshechoes)\
**Post date:** [October 6, 2026, 11:53am UTC](https://qa.fmod.com/t/fmod-core-ios-https-internet-streaming-fails/24550/1 "2026-10-06T11:53:50Z")

</div>

FMOD version: 2.03.08

**Platform:** iOS (Core API). Reproduced on both iOS Simulator (iPhone 17 Pro, Simulator runtime iOS 26.5 and 27.0) and a physical device (iOS 26.6.1).

`System::createSound` / `createStream` against any **HTTPS** URL fails on the first attempt. The failure happens immediately after `SystemI::createSoundInternal`, before any meaningful data transfer with:

`[LOG] FMOD_OS_Net_Read : Connection reset by peer.`

or:

`*** Error: End of file unexpectedly reached while trying to read essential data (truncated?).`

The same request succeeds instantly and completely over plain HTTP (no TLS), and the platform’s own TLS stack (Safari, curl) succeeds against the exact same HTTPS endpoint, from the same device, on the same network, at the same time. This (I think) means the failure is in FMOD’s own TLS/HTTPS client rather than anything server- or network-side.

I built a minimal repro (FMOD’s bundled 3d Core API example, modified only in sound-loading code) and systematically eliminated every variable I could think of:

- http 1.1 vs 2.0
- tls 1.2 vs 1.3
- mp4 vs mp3
- using nonblockcallback
- Certificate trust (safari worked fine)
- Simulator vs physical device
- different backend serving the data (local python server vs GCS)

Is this a known issue?  
Is this an internal issue and could you confirm it’s working (or not) your end?

Code example below:

```auto
/*==============================================================================
3D Example
Copyright (c), Firelight Technologies Pty, Ltd 2004-2025.

This example shows how to basic 3D positioning of sounds.

For information on using FMOD example code in your own programs, visit
https://www.fmod.com/legal
==============================================================================*/
#include "fmod.hpp"
#include "fmod_errors.h"
#include "common.h"

const int INTERFACE_UPDATETIME = 50; // 50ms update for interface
const float DISTANCEFACTOR = 1.0f; // Units per meter. I.e feet would = 3.28. centimeters would = 100.

int FMOD_Main()
{
    FMOD::System *system;
    FMOD::Sound *sound1, *sound2, *sound3;
    FMOD::Channel *channel1 = 0, *channel2 = 0, *channel3 = 0;
    FMOD_RESULT result;
    bool listenerflag = true;
    FMOD_VECTOR listenerpos = { 0.0f, 0.0f, -1.0f * DISTANCEFACTOR };
    void *extradriverdata = 0;
    int outputrate;
    int fade_ms = 2000;

    Common_Init(&extradriverdata);

    /*
        Create a System object and initialize.
    */
    result = FMOD::System_Create(&system);
    ERRCHECK(result);
    
    result = system->init(100, FMOD_INIT_NORMAL, extradriverdata);
    ERRCHECK(result);
    
    /*
        Set the distance units. (meters/feet etc).
    */
    result = system->set3DSettings(1.0, DISTANCEFACTOR, 1.0f);
    ERRCHECK(result);

    /*
        Load some sounds
    */
    result = system->createStream("https://dolphin.echoes.xyz/sounds/68cacdf906a55799ea050aa9/k60sus7ovj1yc2mw.mp4",
                                   FMOD_3D, 0, &sound1);
    ERRCHECK(result);
    result = sound1->set3DMinMaxDistance(0.5f * DISTANCEFACTOR, 5000.0f * DISTANCEFACTOR);
    ERRCHECK(result);
    result = sound1->setMode(FMOD_LOOP_NORMAL);
    ERRCHECK(result);

    result = system->createSound(Common_MediaPath("jaguar.wav"), FMOD_3D, 0, &sound2);
    ERRCHECK(result);
    result = sound2->set3DMinMaxDistance(0.5f * DISTANCEFACTOR, 5000.0f * DISTANCEFACTOR);
    ERRCHECK(result);
    result = sound2->setMode(FMOD_LOOP_NORMAL);
    ERRCHECK(result);

    result = system->createSound(Common_MediaPath("swish.wav"), FMOD_2D, 0, &sound3);
    ERRCHECK(result);
    
    result = system->getSoftwareFormat(&outputrate, 0, 0);

    /*
        Play sounds at certain positions
    */
    {
        FMOD_VECTOR pos = { -10.0f * DISTANCEFACTOR, 0.0f, 0.0f };
        FMOD_VECTOR vel = { 0.0f, 0.0f, 0.0f };

        result = system->playSound(sound1, 0, true, &channel1);
        ERRCHECK(result);
        result = channel1->set3DAttributes(&pos, &vel);
        ERRCHECK(result);
        result = channel1->setPaused(false);
        ERRCHECK(result);
        result = channel1->setVolume(0.5f);
    }

    {
        FMOD_VECTOR pos = { 15.0f * DISTANCEFACTOR, 0.0f, 0.0f };
        FMOD_VECTOR vel = { 0.0f, 0.0f, 0.0f };

        result = system->playSound(sound2, 0, true, &channel2);
        ERRCHECK(result);
        result = channel2->set3DAttributes(&pos, &vel);
        ERRCHECK(result);
        result = channel2->setPaused(false);
        ERRCHECK(result);
    }

    /*
        Main loop
    */
    do
    {
        Common_Update();

        if (Common_BtnPress(BTN_ACTION1))
        {
            unsigned long long parentclock;
            channel1->getDSPClock(nullptr, &parentclock);
            
            bool isplaying;
            result = channel1->isPlaying(&isplaying);
            
            if (!isplaying) {
                result = system->playSound(sound1, 0, true, &channel1);
                ERRCHECK(result);
            }
            
            float volume;
            result = channel1->getVolume(&volume);
            ERRCHECK(result);
            printf("Volume is %f", volume);
            
            bool paused;
            result = channel1->getPaused(&paused);
            ERRCHECK(result);
            
            unsigned int numpoints;
            result = channel1->getFadePoints(&numpoints, nullptr, nullptr);
            if (numpoints > 0) {
                unsigned long long point_dspclock[numpoints];
                float point_volume[numpoints];
                result = channel1->getFadePoints(&numpoints, point_dspclock, point_volume);
                if (result != FMOD_OK) {
                    ERRCHECK(result);
                    return;
                }
                // it was faded
                paused = true;
            }
            
            
            
            // Clear existing fade points first
            result = channel1->removeFadePoints(0, __LONG_MAX__ );
            ERRCHECK(result);
            
            if (paused) {
                // Fade in from pause
                unsigned long long fadeOffset = (outputrate * fade_ms) / 1000;
                unsigned long long fadePoint = parentclock + fadeOffset;
                
                result = channel1->setDelay(0, 0);
                ERRCHECK(result);
                
                // Set up fade in
                result = channel1->addFadePoint(parentclock, 0.0f);
                ERRCHECK(result);
                result = channel1->addFadePoint(fadePoint, 1.0f);
                ERRCHECK(result);
                
                channel1->setPaused(false);
            } else {
                // Fade out and pause
                unsigned long long parentclock;
                result = channel1->getDSPClock(nullptr, &parentclock);
                ERRCHECK(result);
                
                unsigned long long fadeOffset = (outputrate * fade_ms) / 1000;
                unsigned long long fadePoint = parentclock + fadeOffset;
                
                // Set up fade out
                result = channel1->addFadePoint(parentclock, 1.0f);
                ERRCHECK(result);
                result = channel1->addFadePoint(fadePoint, 0.0f);
                ERRCHECK(result);
                
                // Use a callback or timer to pause after fade completes
                result = channel1->setDelay(0, fadePoint - 10); // +10ms buffer
                ERRCHECK(result);
            }
        }

        if (Common_BtnPress(BTN_ACTION2))
        {
            bool paused;
            channel2->getPaused(&paused);
            channel2->setPaused(!paused);
        }

        if (Common_BtnPress(BTN_ACTION3))
        {
            result = system->playSound(sound3, 0, false, &channel3);
            ERRCHECK(result);
        }

        if (Common_BtnPress(BTN_MORE))
        {
            listenerflag = !listenerflag;
        }

        if (!listenerflag)
        {
            if (Common_BtnDown(BTN_LEFT))
            {
                listenerpos.x -= 1.0f * DISTANCEFACTOR;
                if (listenerpos.x < -24 * DISTANCEFACTOR)
                {
                    listenerpos.x = -24 * DISTANCEFACTOR;
                }
            }

            if (Common_BtnDown(BTN_RIGHT))
            {
                listenerpos.x += 1.0f * DISTANCEFACTOR;
                if (listenerpos.x > 23 * DISTANCEFACTOR)
                {
                    listenerpos.x = 23 * DISTANCEFACTOR;
                }
            }
        }

        // ==========================================================================================
        // UPDATE THE LISTENER
        // ==========================================================================================
        {
            static float t = 0;
            static FMOD_VECTOR lastpos = { 0.0f, 0.0f, 0.0f };
            FMOD_VECTOR forward = { 0.0f, 0.0f, 1.0f };
            FMOD_VECTOR up = { 0.0f, 1.0f, 0.0f };
            FMOD_VECTOR vel;

            if (listenerflag)
            {
                listenerpos.x = (float)sin(t * 0.05f) * 24.0f * DISTANCEFACTOR; // left right pingpong
            }

            // *********NOTE******* READ NEXT COMMENT!!!!!
            // vel = how far we moved last FRAME (m/f), then time compensate it to SECONDS (m/s).
            vel.x = (listenerpos.x - lastpos.x) * (1000 / INTERFACE_UPDATETIME);
            vel.y = (listenerpos.y - lastpos.y) * (1000 / INTERFACE_UPDATETIME);
            vel.z = (listenerpos.z - lastpos.z) * (1000 / INTERFACE_UPDATETIME);

            // store pos for next time
            lastpos = listenerpos;

            result = system->set3DListenerAttributes(0, &listenerpos, &vel, &forward, &up);
            ERRCHECK(result);

            t += (30 * (1.0f / (float)INTERFACE_UPDATETIME)); // t is just a time value .. it increments in 30m/s steps in this example
        }

        result = system->update();
        ERRCHECK(result);

        // Create small visual display.
        char s[80] = "|.............<1>......................<2>.......|";
        s[(int)(listenerpos.x / DISTANCEFACTOR) + 25] = 'L';

        Common_Draw("==================================================");
        Common_Draw("3D Example.");
        Common_Draw("Copyright (c) Firelight Technologies 2004-2025.");
        Common_Draw("==================================================");
        Common_Draw("");
        Common_Draw("Press %s to toggle sound 1 (16bit Mono 3D)", Common_BtnStr(BTN_ACTION1));
        Common_Draw("Press %s to toggle sound 2 (8bit Mono 3D)", Common_BtnStr(BTN_ACTION2));
        Common_Draw("Press %s to play a sound (16bit Stereo 2D)", Common_BtnStr(BTN_ACTION3));
        Common_Draw("Press %s or %s to move listener in still mode", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT));
        Common_Draw("Press %s to toggle listener auto movement", Common_BtnStr(BTN_MORE));
        Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
        Common_Draw("");
        Common_Draw(s);

        Common_Sleep(INTERFACE_UPDATETIME - 1);
    } while (!Common_BtnPress(BTN_QUIT));

    /*
        Shut down
    */
    result = sound1->release();
    ERRCHECK(result);
    result = sound2->release();
    ERRCHECK(result);
    result = sound3->release();
    ERRCHECK(result);

    result = system->close();
    ERRCHECK(result);
    result = system->release();
    ERRCHECK(result);

    Common_Close();

    return 0;
}

```

---

<div class="post-metadata">

**Author:** ![Andrew](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/andrew/32/261_2.png) [@Andrew](https://qa.fmod.com/u/Andrew)\
**Post date:** [October 6, 2026, 9:50pm UTC](https://qa.fmod.com/t/fmod-core-ios-https-internet-streaming-fails/24550/2 "2026-10-06T21:50:09Z")

</div>

Sorry, we don’t yet support https internet streams. I’ll add your feedback to the task in our tracker.

---

<div class="post-metadata">

**Author:** ![joshechoes](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/joshechoes/32/558_2.png) [@joshechoes](https://qa.fmod.com/u/joshechoes)\
**Post date:** [October 7, 2026, 1:10pm UTC](https://qa.fmod.com/t/fmod-core-ios-https-internet-streaming-fails/24550/3 "2026-10-07T13:10:59Z")

</div>

It always used to support it, it’s in the documentation: [https://www.fmod.com/docs/2.04/api/loading-and-playing-sounds-in-the-core-api.html#internet-streaming](https://www.fmod.com/docs/2.04/api/loading-and-playing-sounds-in-the-core-api.html#internet-streaming)

I swear this was working before! And in fact it works over plain HTTP as mentioned, so the issue must be with the HTTPS negotiation – in FMOD’s internal net client.
