Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

This exception means Android is restoring a fragment from saved state but cannot instantiate its class with the fragment manager’s configured factory. For the usual fix, make a Java nested fragment public static (or move it to its own public class), remove Kotlin’s inner modifier, use a no-argument constructor with the default factory, and pass initialization values in a Bundle. If constructor injection is intentional, install an AndroidX FragmentFactory before the activity calls super.onCreate().

Why this error appears after the screen first works

The fragment manager records fragment classes and state so it can restore them later. That may happen after a configuration change such as rotation, when returning to a saved task, or after Android recreates a process that was in the background. On the first launch, your code may construct a fragment directly; during restoration, the manager has to create it from its class name using the configured factory. A class that depends on an enclosing activity, is inaccessible, or requires constructor arguments may not be recreatable that way. See Android’s FragmentManager guide and fragment state guide.

Find the fragment named in the exception

  1. Read the full stack trace and note the fragment class named in the exception.
  2. Check its declaration: is it nested inside an activity or another class, declared private or package-private, local to a method, or anonymous?
  3. Check its constructors. If the default factory is being used, the class must be constructible without required arguments.
  4. Check the imports. androidx.fragment.app.Fragment belongs with AndroidX’s support fragment manager and APIs; android.app.Fragment is the legacy platform API. Do not mix a fragment class with the other API’s manager. The platform fragment API is deprecated; see the platform reference.

Fix Java fragment declarations

A non-static Java inner class implicitly holds a reference to an instance of its enclosing class. The fragment manager cannot supply that hidden activity reference when it recreates the fragment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// Not independently instantiable
public class MainActivity extends AppCompatActivity {
    public class DetailsFragment extends Fragment {
    }
}

As a minimal repair, make a nested fragment both public and static:

public class MainActivity extends AppCompatActivity {
    public static class DetailsFragment extends Fragment {
        public DetailsFragment() {
        }
    }
}

Usually, a separate top-level class is clearer and less coupled to the activity:

public class DetailsFragment extends Fragment {
    public DetailsFragment() {
    }
}

A top-level class does not use static, but it must be accessible to the factory. A package-private top-level class or a private constructor can still cause an instantiation failure. In Java, put the fragment in its own file if necessary to declare it public.

Fix Kotlin fragment declarations

Kotlin nested classes are static-like by default. The inner modifier is what gives the class an implicit reference to its outer instance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// Not suitable for default recreation
class MainActivity : AppCompatActivity() {
    inner class DetailsFragment : Fragment()
}

Remove inner, or preferably declare the fragment at top level:

class MainActivity : AppCompatActivity() {
    class DetailsFragment : Fragment()
}

// Often clearer as a top-level class
class DetailsFragment : Fragment()

A Kotlin class with required constructor parameters is still incompatible with the default factory, even if it is top-level and public.

Pass initialization data through fragment arguments

Do not add constructor parameters just to pass an item ID or display mode. Use a factory method as a convenient convention, set arguments before the fragment is added, and read them when the fragment is created. AndroidX documents that fragment arguments are saved and restored with the fragment in its Fragment reference.

Java

public class DetailsFragment extends Fragment {
    private static final String ARG_ITEM_ID = "item_id";

    public DetailsFragment() {
        // Used by the default FragmentFactory
    }

    public static DetailsFragment newInstance(String itemId) {
        DetailsFragment fragment = new DetailsFragment();
        Bundle args = new Bundle();
        args.putString(ARG_ITEM_ID, itemId);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String itemId = requireArguments().getString(ARG_ITEM_ID);
        // Load or identify the required data using itemId.
    }
}

Kotlin

class DetailsFragment : Fragment() {
    private val itemId: String by lazy {
        requireArguments().getString(ARG_ITEM_ID)
            ?: error("Missing item_id")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Use itemId here; access views later, after the view is created.
    }

    companion object {
        private const val ARG_ITEM_ID = "item_id"

        fun newInstance(itemId: String) = DetailsFragment().apply {
            arguments = bundleOf(ARG_ITEM_ID to itemId)
        }
    }
}

Arguments are for small initialization inputs: IDs, strings, numbers, booleans, and supported parcelable or serializable values. Do not put an Activity, Context, view, binding, listener, adapter, repository, database connection, thread, or large object graph in a bundle. Pass an identifier and obtain data or runtime dependencies through a repository, a ViewModel, dependency injection, or an appropriate lifecycle callback. Set arguments before adding or attaching the fragment; changing them after state has been saved is too late.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a custom FragmentFactory for constructor injection

AndroidX’s default FragmentFactory expects a usable no-argument constructor. A custom factory is appropriate when constructor injection is a deliberate architecture choice and the fragment needs services that do not belong in arguments. It is not necessary for a fragment that only needs an ID. See the FragmentFactory reference and the factory installation guidance.

Install the factory on the manager that owns the fragments, before super.onCreate() so it is available when saved fragments are restored.

Kotlin

class AppFragmentFactory(
    private val repository: ItemRepository
) : FragmentFactory() {
    override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
        return when (className) {
            DetailsFragment::class.java.name -> DetailsFragment(repository)
            else -> super.instantiate(classLoader, className)
        }
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        supportFragmentManager.fragmentFactory =
            AppFragmentFactory(AppRepositoryProvider.repository)
        super.onCreate(savedInstanceState)
    }
}

class DetailsFragment(
    private val repository: ItemRepository
) : Fragment(R.layout.fragment_details)

Java

public class AppFragmentFactory extends FragmentFactory {
    private final ItemRepository repository;

    public AppFragmentFactory(ItemRepository repository) {
        this.repository = repository;
    }

    @NonNull
    @Override
    public Fragment instantiate(
            @NonNull ClassLoader classLoader,
            @NonNull String className) {
        if (className.equals(DetailsFragment.class.getName())) {
            return new DetailsFragment(repository);
        }
        return super.instantiate(classLoader, className);
    }
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    getSupportFragmentManager().setFragmentFactory(
        new AppFragmentFactory(AppRepositoryProvider.getRepository())
    );
    super.onCreate(savedInstanceState);
}

For AndroidX fragments hosted by an AppCompatActivity, this example configures supportFragmentManager. If a nested child manager owns the fragment, ensure its factory is configured as appropriate too. A factory that is installed too late or on a different manager will not create the fragments being restored. Unhandled classes should fall through to super.instantiate().

Keep the different kinds of state in the right place

  • Arguments: immutable inputs needed to identify or initialize the fragment, such as an item ID.
  • onSaveInstanceState(): small, changing UI or fragment state that must be restored, such as a selected tab or in-progress field value.
  • ViewModel: in-memory screen state that should survive configuration changes.
  • SavedStateHandle: appropriate small state that also needs process-death restoration when used with the relevant architecture components.
  • Repository or other data layer: durable or larger business data that should be reloaded rather than serialized into fragment state.

These mechanisms solve different problems; making a fragment recreatable does not automatically preserve every changing value. Consult Android’s guidance on saving fragment state. Read arguments and initialize non-view state in onCreate(), but access views only after onCreateView() or onViewCreated(). Clear view bindings in onDestroyView() so they do not retain an obsolete view after recreation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Dialogs, navigation, and initial fragment creation

An anonymous DialogFragment subclass has the same restoration problem as an anonymous ordinary fragment. Replace it with a named class, give it a no-argument constructor when using the default factory, and pass dialog inputs in arguments. For results, prefer the Fragment Result API, a shared ViewModel, or another lifecycle-aware mechanism rather than storing an activity callback in the dialog.

Navigation destinations and fragments on the back stack are also subject to restoration. Make sure the named destination class is recreatable and that any custom factory is installed on the manager used by that navigation setup.

When adding the initial fragment manually, avoid adding a duplicate over one the fragment manager is already restoring:

if (savedInstanceState == null) {
    getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.container, DetailsFragment.newInstance("42"))
        .commit();
}

Common failed fixes

  • Suppressing ValidFragment lint: a suppression hides a warning; it does not make a class public, static, or constructible. The runtime restoration failure remains.
  • Adding an empty constructor but losing required inputs: pair the constructor change with arguments, or use a properly configured factory.
  • Making one class static while an anonymous or local fragment is still used: inspect the actual class named in the stack trace and other fragment creation sites.
  • Passing an activity listener or service through arguments: pass small data, then establish communication or obtain dependencies through lifecycle-aware mechanisms.
  • Adding the fragment on every onCreate(): this can duplicate a fragment already restored by the manager; guard initial creation with savedInstanceState == null.
  • Installing the factory after restoration begins: assign it before super.onCreate() and on the correct manager.

Verify the repair

  1. Confirm the class is independently instantiable: public and top-level, or public static in Java; not inner in Kotlin.
  2. Confirm the default factory can call a no-argument constructor, or verify the custom factory handles the class.
  3. Confirm arguments are set before the fragment is added and contain only supported small values.
  4. Rotate the device or emulator and also try a configuration change such as changing font scale or language.
  5. Navigate away and back to exercise back-stack restoration; reopen dialogs and test deep links or navigation destinations if used.
  6. Test process recreation, not only rotation: put the app in the background and exercise a process-death restoration scenario. A force-stop alone may not reproduce every saved-task path, so verify that the app returns through a genuine restored task where possible.

If the crash persists, re-check the class named in the exception, visibility, constructor signature, actual fragment imports, anonymous subclasses, the manager that owns the fragment, and whether the build being tested contains the change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.