diff --git includes/callback.inc includes/callback.inc
index 644ee3b..898629b 100644
--- includes/callback.inc
+++ includes/callback.inc
@@ -16,6 +16,24 @@ interface SearchApiAlterCallbackInterface {
   public function __construct(SearchApiIndex $index, array $options = array());
 
   /**
+   * Check whether this data-alter callback is applicable for a certain index.
+   *
+   * This can be used for hiding the callback on the index's "Workflow" tab. To
+   * avoid confusion, you should only use criteria that are immutable, such as
+   * the index's entity type. Also, since this is only used for UI purposes, you
+   * should not completely rely on this to ensure certain index configurations
+   * and at least throw an exception with a descriptive error message if this is
+   * violated on runtime.
+   *
+   * @param SearchApiIndex $index
+   *   The index to check for.
+   *
+   * @return boolean
+   *   TRUE if the callback can run on the given index; FALSE otherwise.
+   */
+  public function supportsIndex(SearchApiIndex $index);
+
+  /**
    * Display a form for configuring this callback.
    *
    * @return array
@@ -119,6 +137,28 @@ abstract class SearchApiAbstractAlterCallback implements SearchApiAlterCallbackI
   }
 
   /**
+   * Check whether this data-alter callback is applicable for a certain index.
+   *
+   * This can be used for hiding the callback on the index's "Workflow" tab. To
+   * avoid confusion, you should only use criteria that are immutable, such as
+   * the index's entity type. Also, since this is only used for UI purposes, you
+   * should not completely rely on this to ensure certain index configurations
+   * and at least throw an exception with a descriptive error message if this is
+   * violated on runtime.
+   *
+   * The default implementation always returns TRUE.
+   *
+   * @param SearchApiIndex $index
+   *   The index to check for.
+   *
+   * @return boolean
+   *   TRUE if the callback can run on the given index; FALSE otherwise.
+   */
+  public function supportsIndex(SearchApiIndex $index) {
+    return TRUE;
+  }
+
+  /**
    * Display a form for configuring this callback.
    *
    * @return array
diff --git includes/callback_bundle_filter.inc includes/callback_bundle_filter.inc
index fbe9ba4..f19deb4 100644
--- includes/callback_bundle_filter.inc
+++ includes/callback_bundle_filter.inc
@@ -6,6 +6,10 @@
  */
 class SearchApiAlterBundleFilter extends SearchApiAbstractAlterCallback {
 
+  public function supportsIndex(SearchApiIndex $index) {
+    return self::hasBundles(entity_get_info($index->entity_type));
+  }
+
   public function alterItems(array &$items) {
     $info = entity_get_info($this->index->entity_type);
     if (self::hasBundles($info) && isset($this->options['bundles'])) {
diff --git includes/processor.inc includes/processor.inc
index e1745e5..1de6ece 100644
--- includes/processor.inc
+++ includes/processor.inc
@@ -25,6 +25,24 @@ interface SearchApiProcessorInterface {
   public function __construct(SearchApiIndex $index, array $options = array());
 
   /**
+   * Check whether this processor is applicable for a certain index.
+   *
+   * This can be used for hiding the processor on the index's "Workflow" tab. To
+   * avoid confusion, you should only use criteria that are immutable, such as
+   * the index's entity type. Also, since this is only used for UI purposes, you
+   * should not completely rely on this to ensure certain index configurations
+   * and at least throw an exception with a descriptive error message if this is
+   * violated on runtime.
+   *
+   * @param SearchApiIndex $index
+   *   The index to check for.
+   *
+   * @return boolean
+   *   TRUE if the processor can run on the given index; FALSE otherwise.
+   */
+  public function supportsIndex(SearchApiIndex $index);
+
+  /**
    * Display a form for configuring this processor.
    * Since forcing users to specify options for disabled processors makes no
    * sense, none of the form elements should have the '#required' attribute set.
@@ -135,6 +153,10 @@ abstract class SearchApiAbstractProcessor implements SearchApiProcessorInterface
     $this->options = $options;
   }
 
+  public function supportsIndex(SearchApiIndex $index) {
+    return TRUE;
+  }
+
   public function configurationForm() {
     return array();
   }
diff --git search_api.admin.inc search_api.admin.inc
index e16fbb3..2c0038a 100644
--- search_api.admin.inc
+++ search_api.admin.inc
@@ -1109,6 +1109,12 @@ function search_api_admin_index_workflow(array $form, array &$form_state, Search
       unset($callback_objects[$name]);
       continue;
     }
+    if (!$callback_objects[$name]->supportsIndex($index)) {
+      unset($callback_info[$name]);
+      unset($callbacks[$name]);
+      unset($callback_objects[$name]);
+      continue;
+    }
   }
   $form_state['callbacks'] = $callback_objects;
   $form['#callbacks'] = $callbacks;
@@ -1199,6 +1205,12 @@ function search_api_admin_index_workflow(array $form, array &$form_state, Search
       unset($processor_objects[$name]);
       continue;
     }
+    if (!$processor_objects[$name]->supportsIndex($index)) {
+      unset($processor_info[$name]);
+      unset($processors[$name]);
+      unset($processor_objects[$name]);
+      continue;
+    }
   }
   $form_state['processors'] = $processor_objects;
   $form['#processors'] = $processors;
