Diagnostic Reference

Unity 6.3 LTS + Meta Quest 3S
Specific Situations & Behaviors

Find your exact symptom and follow the targeted fix. Each scenario explains why it happens and the shortest path to resolution.

Which guide should I use?

Use this page if you've built to the Quest successfully before and now ONE specific thing is going wrong (a particular error message, a specific visual problem, controllers not working, etc.).

Use the Step-by-Step Guide if you've never built to the Quest before, or if you're not sure what's wrong and want to check every setting from the start.

Vocabulary — what do these words mean?
OpenXR
The standard system Unity uses to talk to VR headsets like the Quest.
XR Origin
The "rig" in your scene that represents the player's headset and hands. Replaces the regular Camera for VR.
Tracked Pose Driver
A component on the camera that makes it follow the headset's movement.
AndroidManifest
A file inside every Android app that tells the device what kind of app it is and what permissions it needs.
Intent / category
A tag inside the AndroidManifest. The "VR" category tells the Quest to launch the app in 3D immersive mode, not as a flat phone app.
Multi-view
A way of drawing both eyes at the same time (faster). The opposite is Multi-pass (slower, draws each eye separately).
URP
Universal Render Pipeline — Unity's modern graphics system, used by most Quest projects.
IL2CPP
The system Unity uses to convert your C# code into a form the Quest can run. Required for Quest builds.
ARM64
The type of processor inside the Quest 3S. Your build must target this architecture.
Linear color space
A more accurate way of handling colors. VR needs this — the older "Gamma" mode makes everything look wrong.
Gradle
The build tool Unity uses behind the scenes to package your app into an APK file.
APK
The file format for an Android app — what gets installed on the Quest.
Sideloading
Installing an app that did NOT come from the official store. Anything you build yourself is sideloaded.
adb
Android Debug Bridge — a small program that lets your PC talk to the Quest through a USB cable.
Horizon OS
The operating system that runs on the Quest headset, made by Meta.
Jump to section
Click any item below to expand the full instructions and fix steps. Items marked "More Advanced" use the command line.
1

Build fails — no APK is created

Errors happen in Unity's build process before anything reaches the headset
Build error
1.1 JdkImageTransform failed / android-36 error
Error mentions core-for-system-modules.jar and a path inside C:\Program Files\Unity\
Why it happens: Unity 6.3's built-in Android SDK is stored in C:\Program Files\Unity\. On school computers, that folder is locked so it can't be changed. The build process tries to modify a file there and fails because it doesn't have permission.
  1. Lower the Target API level (fastest fix)

    Open Player Settings → Other Settings → Target API Level.

    Change it from Android 16 (API 36) to Android 14 (API 34) or Android 15 (API 35).

    Delete the cache folder at C:\Users\[your-username]\.gradle\caches\ and try building again.

  2. Install a writable Android SDK (better long-term fix)

    Download Android Studio and install its SDK to a folder you have permission to write to: C:\Users\[you]\AppData\Local\Android\Sdk.

    Point Unity to it: Edit → Preferences → External Tools → Android SDK. Uncheck "Unity bundled" and browse to the new folder.

  3. Delete the build caches

    Delete BOTH of these folders:

    • C:\Users\[you]\.gradle\caches\
    • Inside your Unity project: Library\Bee\

    Note: The build keeps a copy of broken work in these caches. Even if you fix the original problem, the cache will keep using the broken version until you delete it.

Build completes and creates an APK file in your build folder.
Build error
1.2 Gradle: "SDK is read-only" warnings
Lots of messages about "Exception while marshalling … package.xml. Probably the SDK is read-only"
Why it happens: Same root cause as scenario 1.1 — the Android SDK is in a folder you don't have permission to write to. You'll see these warnings flooding your build output.
  1. Install a writable SDK via Android Studio

    Download Android Studio. During installation, accept the default SDK location: AppData\Local\Android\Sdk.

    In Android Studio's SDK Manager, install: SDK Platform 34 or 35, Build-tools 36.0.0, Command-line tools 16, and NDK r27c.

  2. Point Unity to the new SDK

    Uncheck "Android SDK Tools Installed with Unity (Recommended)" and set the path to your new SDK folder.

    Do the same for NDK: uncheck "Installed with Unity" and set the path to AppData\Local\Android\Sdk\ndk\27.2.12479018.

Warnings disappear. Build completes cleanly.
Build error
1.3 compileReleaseJavaWithJavac FAILED
Build fails during the Java compilation step
Why it happens: Unity 6.3 needs Java JDK 17 to build Quest apps. If your computer has an older version of Java installed (like Java 8) and your settings point to it, the build fails.
  1. Let Unity use its bundled JDK

    Open Edit → Preferences → External Tools.

    Make sure "JDK Installed with Unity (Recommended)" IS checked.

    Note: Unity 6.3 comes with JDK 17 built in. Use it unless you have a specific reason not to.

  2. Clear the build cache and rebuild

    Delete the folder Library\Bee\ inside your Unity project.

    This forces Unity to recompile everything from scratch with the correct JDK.

Build completes successfully.
Section 2 — App not appearing on headset
2

App not appearing on the headset

The build succeeded, but you can't find your app in the Quest library
Not found
2.1 App is missing from Unknown Sources after a successful build More Advanced
Unity says "Build succeeded" but you can't find the app anywhere on the headset
Why it happens: The APK file was created, but it didn't actually copy onto the headset. This usually happens when "Build and Run" lost its connection partway through, or your PC wasn't trusted by the headset.
  1. Check that your PC is trusted by the headset

    Open Command Prompt and run:

    C:\> adb devices

    The result should say device, NOT unauthorized.

    If it says unauthorized: put on the headset, look for the "Allow USB Debugging" popup, check "Always allow from this computer," and click Allow. Then run the command again.

  2. Install the APK manually

    Find the APK file Unity created (in the folder you chose during Build Settings). Then run this in Command Prompt:

    C:\> adb install -r "C:\path\to\your\game.apk"

    Replace the path with where your APK actually is. The -r means "replace if already installed."

  3. Look in the Unknown Sources filter

    Put the headset on. Open the App Library.

    At the top right of the library, tap the filter dropdown and select Unknown Sources.

    Note: Apps you build yourself only show up in this filtered view, not in the main library where store apps appear.

  4. Check Developer Mode is on

    On your phone, open the Meta Horizon app. Tap on your headset, then tap "Developer Mode."

    The toggle must be ON.

    Note: Without Developer Mode, the headset refuses to install apps that didn't come from the store.

Your app appears in Unknown Sources and can be opened.
Wrong icon
2.2 App shows the default Unity cube icon, not a VR icon
A generic Unity cube icon usually means the app isn't recognised as a VR app
Why it happens: Your app's AndroidManifest file is missing the VR tag that tells the Quest "this is a VR app." When you turn on Meta Quest Support in OpenXR settings, that tag gets added automatically — so if it's missing, that setting is probably off.
  1. Turn on Meta Quest Support

    Check the box next to Meta Quest Support. Rebuild and reinstall.

  2. Add a custom app icon

    Open Player Settings → Android tab → Icon and upload an image to use as your app's icon.

    Note: Even with everything correct, if you don't upload an icon, Unity will always use its default cube. So an icon that LOOKS wrong might just mean you never added one.

App shows a custom icon and launches as a VR app.
Section 3 — App launches but shows black screen
3

App launches but shows only a black screen

The most common category — there are several possible causes
Black screen
3.1 Black screen right from launch — nothing ever shows up
The Quest shows loading dots, then the app opens to pure black
Why it happens: Meta Quest Support is not turned on in your OpenXR settings. Without it, your app is missing the tags that tell the Quest to launch in VR mode, so the VR display never starts up.
  1. Turn on Meta Quest Support and add Quest 3S as a target

    Check the box next to Meta Quest Support.

    Click the gear icon next to it and check Quest 3S (and Quest 3) under Target Devices.

  2. Add a controller interaction profile

    In the same OpenXR settings, find the Interaction Profiles section.

    Click + and add Meta Quest Touch Plus Controller Profile.

    Note: Without a controller profile, the VR session can't fully start up.

  3. Run Project Validation

    Click Fix All to fix any red errors. Then rebuild and reinstall.

App launches into the 3D environment, visible in the headset.
Black screen
3.2 Build installs and starts, but the headset view stays black
No errors during build. The app appears to launch, but you can't see anything in the headset.
Why it happens: The Quest 3S is strict about its display settings. Even when the build succeeds, the wrong stereo render mode or camera setup means nothing actually shows in the headset.
  1. Change Render Mode to Multi-view

    Set Render Mode to Multi-view.

    Note: "Multi-pass" mode often shows a black screen on the Quest 3S. Multi-view is the safer choice.

  2. Check the Tracked Pose Driver bindings

    Click on your Main Camera in the Hierarchy. In the Inspector, find the Tracked Pose Driver component.

    Both inputs must be bound:

    • Position Input → centerEyePosition [XR HMD]
    • Rotation Input → centerEyeRotation [XR HMD]

    Note: If either is empty or set to a keyboard/mouse input, the camera won't follow the headset — it stays at a fixed point that's often inside geometry, showing black.

  3. Make sure Color Space is Linear

    Set to Linear.

    Note: The older "Gamma" color mode combined with OpenGLES + OpenXR creates a black screen on the headset.

The headset displays your scene with proper stereo rendering and head tracking.
Black screen
3.3 Log shows "xrGetVulkanGraphicsDevice2KHR" errors More Advanced
A Vulkan graphics error you can only see by reading the headset's log
Why it happens: Vulkan is one of two graphics systems the Quest can use. Sometimes it doesn't get along with OpenXR — usually because your OpenXR plugin is too old for the version of Horizon OS on the headset.
  1. Switch to OpenGLES3 to confirm Vulkan is the cause

    Remove Vulkan from the list and add OpenGLES3. Rebuild.

    If your app now works, you've confirmed Vulkan was the problem.

  2. Update the OpenXR Plugin

    Click "Update" if a newer version is available.

    After updating, switch back to Vulkan and try again.

  3. Turn off Auto Graphics API

    In Graphics APIs settings, uncheck Auto Graphics API and list only Vulkan (or only OpenGLES3).

    Note: Auto mode can pick a graphics system that doesn't work on the Quest.

No more Vulkan errors in the log; app renders correctly.
Black screen
3.4 App runs (you can hear audio) but you can't see anything
Audio plays normally but the view stays completely black
Why it happens: Your VR camera setup isn't quite right. Most common reasons: you have a regular Camera instead of an XR Origin, the Tracked Pose Driver isn't bound, or the camera starts inside a wall or floor.
  1. Check that you have an XR Origin in your scene

    Your Hierarchy must contain this structure:

    XR Origin └─ Camera Offset └─ Main Camera ← Tracked Pose Driver here

    If you only have a plain Camera, delete it and add an XR Origin by right-clicking in the Hierarchy → XR → XR Origin (VR).

  2. Make sure the camera isn't inside geometry

    Click on XR Origin in your Hierarchy. Look at its position in the Inspector.

    Note: If XR Origin is at Y=0 and you have a floor mesh also at Y=0, the camera starts inside the floor — which looks black. Move XR Origin to Y=1.6 (about eye height).

  3. Check URP Renderer Data

    Find your Universal Renderer Data asset (search the Project for t:UniversalRendererData).

    Set Intermediate Texture to Auto and turn OFF Post Processing.

    Note: Effects like Bloom often cause black screens on Quest because they use image formats the headset doesn't support.

  4. Make sure your scene is in Build Settings

    Your scene must be in the "Scenes In Build" list AND have a checkmark.

    Note: If only an empty default scene is built, you'll see a black screen with no errors at all.

The 3D scene appears in the headset and follows your head movement.
Section 4 — Partial or wrong rendering
4

Partial or incorrect rendering

Something renders, but it looks wrong in the headset
Render issue
4.1 App appears as a floating 2D panel, not full VR More Advanced
Your scene renders inside a small flat window in the Quest home environment
Why it happens: Your app launched as a regular 2D Android app instead of a VR app. This means Meta Quest Support wasn't enabled when you built — so your app is missing the VR tag.
  1. Turn on Meta Quest Support (required)

    Check the box next to Meta Quest Support. Rebuild and reinstall.

  2. Check for a conflicting custom manifest

    If you have a file at Assets/Plugins/Android/AndroidManifest.xml, open it and make sure it contains:

    <category android:name="com.oculus.intent.category.VR" />

    A custom manifest overrides the one Unity generates, so it needs the VR tag added by hand.

  3. Uninstall the old version first

    In Command Prompt, run (replace with your actual package name):

    C:\> adb uninstall com.yourcompany.yourgame

    Then install the new build.

    Note: Sometimes old settings stick around when you update an app in place. A clean reinstall makes sure all the new settings take effect.

App launches in full immersive VR, filling your view.
Render issue
4.2 Only one eye renders correctly — the other is black or off-center
When you look through the headset, one lens looks right and one looks wrong
Why it happens: Stereo rendering is set to Multi-pass (which draws each eye separately) instead of Multi-view (which draws both eyes at once). Or you have a post-processing effect that only runs for one eye.
  1. Set Render Mode to Multi-view

    Change Render Mode from Multi-pass to Multi-view.

  2. Turn off Post Processing

    Open your Universal Renderer Data asset and uncheck Post Processing → Enabled.

    If the second eye fixes itself, a post-processing effect was the cause. Turn the effects back on one at a time to find which one is broken.

  3. Check custom shaders

    If you wrote any custom HLSL shaders, they need the macros UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX and UNITY_VERTEX_OUTPUT_STEREO to work with Multi-view.

    Note: Built-in URP shaders already have these. This only matters if you wrote your own.

Both eyes render the same scene with proper 3D depth.
Render issue
4.3 Scene renders but colors look completely wrong
Textures and lighting look different on the headset compared to the editor
Why it happens: Color Space is set to Gamma instead of Linear, or HDR settings don't match the Quest's display.
  1. Set Color Space to Linear

    Set to Linear.

    Note: When you change this, Unity will re-import all your textures. This takes several minutes the first time, but it's normal — don't interrupt it.

  2. Turn off HDR if you don't need it

    In your URP Asset, turn off HDR.

    Note: HDR can make scenes look wrong on Quest unless you configure it specifically for the headset's display. If you don't have a reason to use HDR, leave it off.

Colors match the editor preview when viewed in the headset.
Render issue
4.4 Everything works EXCEPT head tracking — the world doesn't move when you turn your head
The scene is visible and looks correct, but turning your head doesn't change what you see. The view feels "stuck."
Why it happens: The headset's position and rotation aren't being passed to your Main Camera. Either the Tracked Pose Driver is missing or set up wrong, the camera isn't a child of the XR Origin, or the headset's tracking system isn't fully initialized.
  1. Check the Tracked Pose Driver bindings

    Click on your Main Camera in the Hierarchy. In the Inspector, find the Tracked Pose Driver (Input System) component.

    Both inputs must be bound to these specific actions:

    • Position Input → centerEyePosition [XR HMD]
    • Rotation Input → centerEyeRotation [XR HMD]

    Note: If the bindings point to devicePosition or deviceRotation instead of centerEye, head movement may not register correctly. Use the centerEye versions.

  2. Make sure the Main Camera is inside the XR Origin

    Look at your Hierarchy. Your Main Camera must be a child of XR Origin, not floating at the top of the Hierarchy:

    XR Origin └─ Camera Offset └─ Main Camera ← must be HERE, not outside XR Origin

    Note: If the camera is outside the XR Origin, it gets head position data but doesn't get rotated by the XR system. Drag the Main Camera into Camera Offset to fix it.

  3. Remove any extra Tracked Pose Driver components

    Sometimes a camera ends up with TWO Tracked Pose Driver components — one from the old XR Legacy Input system and one from the new Input System.

    On the Main Camera, check the Inspector for any duplicate components. If you see both Tracked Pose Driver AND Tracked Pose Driver (Input System), right-click the older one and Remove Component. Keep only the Input System version.

  4. Check that the XR Origin is at the right "tracking origin mode"

    Click on the XR Origin in your Hierarchy.

    In the Inspector, find the Tracking Origin Mode setting. Set it to Floor for room-scale VR, or Device for seated experiences.

    Note: If this is set to "Not Specified" or left at default, the headset may not provide tracking data correctly.

  5. Check Guardian boundary on the headset

    Put the headset on. If you see a message about setting up a play boundary or Guardian, you must complete that setup before tracking works in apps.

    Move to an area with good lighting and a clear floor. The Quest needs to see its surroundings to track your head position.

    Note: The Quest 3S uses cameras to track head movement. In very dark rooms or completely featureless rooms (like a closet with bare white walls), tracking can fail or stop updating.

When you turn your head, the view rotates smoothly. When you move forward, backward, or side-to-side, you can see around objects in your scene.
Section 5 — App crashes on launch
5

App crashes on launch

The app starts then closes, or shows a "keeps stopping" dialog
Crash
5.1 App opens briefly, then closes with "Application keeps stopping" More Advanced
A crash dialog appears a few seconds after launch
Why it happens: A script in your project is crashing right when the scene loads. The Unity editor is more forgiving and might hide this error — but on the actual headset, the crash kills the whole app.
  1. Get the crash log

    In Command Prompt, run this WHILE launching the app:

    C:\> adb logcat -s Unity AndroidRuntime > "%USERPROFILE%\Desktop\crash_log.txt"

    Open crash_log.txt on your Desktop. Press Ctrl+F and search for FATAL EXCEPTION or NullReferenceException.

    The lines just ABOVE the error name your script and the line that crashed.

  2. Look for missing references in your scripts

    The #1 cause is a script trying to use something that doesn't exist yet. This includes calls to GetComponent(), FindObjectOfType(), or accessing a serialized field you forgot to set in the Inspector.

    Find the script named in the crash log and check the Inspector — make sure every field that has an arrow or slot is filled in.

  3. Check for convex mesh errors

    If your Unity build log showed "Couldn't create a Convex Mesh" warnings, those mesh objects could be crashing physics when the scene loads.

    In each mesh's import settings (or on its MeshCollider component), simplify the mesh or turn OFF Convex.

App finishes loading without crashing.
Crash
5.2 Log shows "Entitlement for packageName not found" More Advanced
App closes silently with almost nothing in the log
Why it happens: The headset isn't in Developer Mode. Horizon OS checks every app to see if it came from the store. If it didn't (sideloaded), and Developer Mode is off, the OS blocks the app before it can even start.
  1. Turn on Developer Mode

    On your phone, open the Meta Horizon app.

    Tap your headset, then tap Developer Mode. Turn the toggle ON.

    Restart your headset after turning it on.

  2. Make sure your Meta account is a verified developer

    Developer Mode requires your Meta account to belong to a developer organization.

    Visit developer.oculus.com and create or join an organization. You may need to add a phone number to your account to verify it.

Your sideloaded apps launch without entitlement errors.
Section 6 — Controllers not working
6

Controllers not working

The scene looks fine but your controllers don't track or interact
Input
6.1 Controllers don't move — hands float at a fixed position
You can see the controller models, but they don't move when you move your hands
Why it happens: No controller interaction profile is set up in OpenXR, or the XR Controller components in your scene point to action bindings that don't exist.
  1. Add the correct interaction profile

    Under Interaction Profiles, add Meta Quest Touch Plus Controller Profile.

    Note: This profile is specifically designed for the Quest 3S controllers.

  2. Check the XR Controller component bindings

    In your Hierarchy, click on the Left Hand and Right Hand controller objects under XR Origin.

    On each one, find the XR Controller component. Make sure Position Action points to a real input action like XRI LeftHand/Position, not an empty or missing one.

  3. Make sure Input Action Assets are connected

    Open Edit → Project Settings → Input System → Default Input Actions.

    Make sure the XRI Default Input Actions asset is set there.

    Note: If this is missing or set wrong, all controller tracking breaks on the headset.

Controllers track properly when you move your hands.
Input
6.2 Controllers track, but you can't grab or interact with objects
Movement works but the ray pointer or direct grab does nothing
Why it happens: The XR Interaction Manager is missing from your scene, your objects don't have the right components to be interactive, or the interaction layers don't match between the controller and the object.
  1. Make sure XR Interaction Manager is in the scene

    Search your Hierarchy for XRInteractionManager.

    If it's missing, create an empty GameObject and add the XR Interaction Manager component to it.

    Note: Without this, no interaction events will fire — controllers can move, but nothing they touch will respond.

  2. Check that your objects have the right components

    Each object you want to grab needs an XR Grab Interactable component (or XR Simple Interactable for trigger zones).

    Each object also needs a Collider. Without one, the controller's ray can't detect the object.

  3. Check the Interaction Layer Masks match

    On the XR Ray Interactor (on your controllers) AND on the XR Grab Interactable (on the object), find the Interaction Layer Mask setting.

    Both must share at least one common layer.

    Note: If the layers don't match, the controller will look right through the object as if it isn't there.

You can grab, hold, and release objects with both controllers.
How do I check what version of Unity / OpenXR I have?

Unity version: In the Unity Hub, look next to your project name. Or inside Unity, click Help → About Unity.

OpenXR Plugin version: Open Window → Package Manager. Click "In Project" in the dropdown at the top. Find "OpenXR Plugin" in the list and click it. The version is shown on the right.

XR Interaction Toolkit version: Same as above, but find "XR Interaction Toolkit" in the list.

Quest headset OS version: Put the headset on. Go to Settings → System → Software Update. Your current version is shown at the top.

Stuck on something not listed here? Show your teacher this guide and tell them which scenario number (like "3.2" or "5.1") you're stuck on. If your problem isn't in any scenario, search the exact error message on Unity Discussions (discussions.unity.com) — most problems have been solved by someone else already.
Tip: Print this guide (Ctrl + P) before starting if you'll be working away from your computer. All expanded sections will be included in the printout.